cifsd: braces {} should be used on all arms of this statement
[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
2254 static void ksmbd_acls_fattr(struct smb_fattr *fattr, struct inode *inode)
2255 {
2256         fattr->cf_uid = inode->i_uid;
2257         fattr->cf_gid = inode->i_gid;
2258         fattr->cf_mode = inode->i_mode;
2259         fattr->cf_dacls = NULL;
2260
2261         fattr->cf_acls = ksmbd_vfs_get_acl(inode, ACL_TYPE_ACCESS);
2262         if (S_ISDIR(inode->i_mode))
2263                 fattr->cf_dacls = ksmbd_vfs_get_acl(inode, ACL_TYPE_DEFAULT);
2264 }
2265
2266 /**
2267  * smb2_open() - handler for smb file open request
2268  * @work:       smb work containing request buffer
2269  *
2270  * Return:      0 on success, otherwise error
2271  */
2272 int smb2_open(struct ksmbd_work *work)
2273 {
2274         struct ksmbd_conn *conn = work->conn;
2275         struct ksmbd_session *sess = work->sess;
2276         struct ksmbd_tree_connect *tcon = work->tcon;
2277         struct smb2_create_req *req;
2278         struct smb2_create_rsp *rsp, *rsp_org;
2279         struct path path;
2280         struct ksmbd_share_config *share = tcon->share_conf;
2281         struct ksmbd_file *fp = NULL;
2282         struct file *filp = NULL;
2283         struct kstat stat;
2284         struct create_context *context;
2285         struct lease_ctx_info *lc = NULL;
2286         struct create_ea_buf_req *ea_buf = NULL;
2287         struct oplock_info *opinfo;
2288         __le32 *next_ptr = NULL;
2289         int req_op_level = 0, open_flags = 0, file_info = 0;
2290         int rc = 0, len = 0;
2291         int contxt_cnt = 0, query_disk_id = 0;
2292         int maximal_access_ctxt = 0, posix_ctxt = 0;
2293         int s_type = 0;
2294         int next_off = 0;
2295         char *name = NULL;
2296         char *stream_name = NULL;
2297         bool file_present = false, created = false, already_permitted = false;
2298         int share_ret, need_truncate = 0;
2299         u64 time;
2300         umode_t posix_mode = 0;
2301         __le32 daccess, maximal_access = 0;
2302
2303         rsp_org = work->response_buf;
2304         WORK_BUFFERS(work, req, rsp);
2305
2306         if (req->hdr.NextCommand && !work->next_smb2_rcv_hdr_off &&
2307             (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)) {
2308                 ksmbd_debug(SMB, "invalid flag in chained command\n");
2309                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
2310                 smb2_set_err_rsp(work);
2311                 return -EINVAL;
2312         }
2313
2314         if (test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
2315                 ksmbd_debug(SMB, "IPC pipe create request\n");
2316                 return create_smb2_pipe(work);
2317         }
2318
2319         if (req->NameLength) {
2320                 if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
2321                     *(char *)req->Buffer == '\\') {
2322                         ksmbd_err("not allow directory name included leading slash\n");
2323                         rc = -EINVAL;
2324                         goto err_out1;
2325                 }
2326
2327                 name = smb2_get_name(share,
2328                                      req->Buffer,
2329                                      le16_to_cpu(req->NameLength),
2330                                      work->conn->local_nls);
2331                 if (IS_ERR(name)) {
2332                         rc = PTR_ERR(name);
2333                         if (rc != -ENOMEM)
2334                                 rc = -ENOENT;
2335                         goto err_out1;
2336                 }
2337
2338                 ksmbd_debug(SMB, "converted name = %s\n", name);
2339                 if (strchr(name, ':')) {
2340                         if (!test_share_config_flag(work->tcon->share_conf,
2341                                                     KSMBD_SHARE_FLAG_STREAMS)) {
2342                                 rc = -EBADF;
2343                                 goto err_out1;
2344                         }
2345                         rc = parse_stream_name(name, &stream_name, &s_type);
2346                         if (rc < 0)
2347                                 goto err_out1;
2348                 }
2349
2350                 rc = ksmbd_validate_filename(name);
2351                 if (rc < 0)
2352                         goto err_out1;
2353
2354                 if (ksmbd_share_veto_filename(share, name)) {
2355                         rc = -ENOENT;
2356                         ksmbd_debug(SMB, "Reject open(), vetoed file: %s\n",
2357                                 name);
2358                         goto err_out1;
2359                 }
2360         } else {
2361                 len = strlen(share->path);
2362                 ksmbd_debug(SMB, "share path len %d\n", len);
2363                 name = kmalloc(len + 1, GFP_KERNEL);
2364                 if (!name) {
2365                         rsp->hdr.Status = STATUS_NO_MEMORY;
2366                         rc = -ENOMEM;
2367                         goto err_out1;
2368                 }
2369
2370                 memcpy(name, share->path, len);
2371                 *(name + len) = '\0';
2372         }
2373
2374         req_op_level = req->RequestedOplockLevel;
2375         if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE)
2376                 lc = parse_lease_state(req);
2377
2378         if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE_LE)) {
2379                 ksmbd_err("Invalid impersonationlevel : 0x%x\n",
2380                         le32_to_cpu(req->ImpersonationLevel));
2381                 rc = -EIO;
2382                 rsp->hdr.Status = STATUS_BAD_IMPERSONATION_LEVEL;
2383                 goto err_out1;
2384         }
2385
2386         if (req->CreateOptions && !(req->CreateOptions & CREATE_OPTIONS_MASK)) {
2387                 ksmbd_err("Invalid create options : 0x%x\n",
2388                         le32_to_cpu(req->CreateOptions));
2389                 rc = -EINVAL;
2390                 goto err_out1;
2391         } else {
2392
2393                 if (req->CreateOptions & FILE_SEQUENTIAL_ONLY_LE &&
2394                     req->CreateOptions & FILE_RANDOM_ACCESS_LE)
2395                         req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE);
2396
2397                 if (req->CreateOptions & (FILE_OPEN_BY_FILE_ID_LE |
2398                         CREATE_TREE_CONNECTION | FILE_RESERVE_OPFILTER_LE)) {
2399                         rc = -EOPNOTSUPP;
2400                         goto err_out1;
2401                 }
2402
2403                 if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
2404                         if (req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE) {
2405                                 rc = -EINVAL;
2406                                 goto err_out1;
2407                         } else if (req->CreateOptions & FILE_NO_COMPRESSION_LE) {
2408                                 req->CreateOptions = ~(FILE_NO_COMPRESSION_LE);
2409                         }
2410                 }
2411         }
2412
2413         if (le32_to_cpu(req->CreateDisposition) >
2414                         le32_to_cpu(FILE_OVERWRITE_IF_LE)) {
2415                 ksmbd_err("Invalid create disposition : 0x%x\n",
2416                         le32_to_cpu(req->CreateDisposition));
2417                 rc = -EINVAL;
2418                 goto err_out1;
2419         }
2420
2421         if (!(req->DesiredAccess & DESIRED_ACCESS_MASK)) {
2422                 ksmbd_err("Invalid desired access : 0x%x\n",
2423                         le32_to_cpu(req->DesiredAccess));
2424                 rc = -EACCES;
2425                 goto err_out1;
2426         }
2427
2428         if (req->FileAttributes && !(req->FileAttributes & ATTR_MASK_LE)) {
2429                 ksmbd_err("Invalid file attribute : 0x%x\n",
2430                         le32_to_cpu(req->FileAttributes));
2431                 rc = -EINVAL;
2432                 goto err_out1;
2433         }
2434
2435         if (req->CreateContextsOffset) {
2436                 /* Parse non-durable handle create contexts */
2437                 context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER);
2438                 if (IS_ERR(context)) {
2439                         rc = check_context_err(context, SMB2_CREATE_EA_BUFFER);
2440                         if (rc < 0)
2441                                 goto err_out1;
2442                 } else {
2443                         ea_buf = (struct create_ea_buf_req *)context;
2444                         if (req->CreateOptions & FILE_NO_EA_KNOWLEDGE_LE) {
2445                                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
2446                                 rc = -EACCES;
2447                                 goto err_out1;
2448                         }
2449                 }
2450
2451                 context = smb2_find_context_vals(req,
2452                                 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST);
2453                 if (IS_ERR(context)) {
2454                         rc = check_context_err(context,
2455                                 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST);
2456                         if (rc < 0)
2457                                 goto err_out1;
2458                 } else {
2459                         ksmbd_debug(SMB,
2460                                 "get query maximal access context\n");
2461                         maximal_access_ctxt = 1;
2462                 }
2463
2464                 context = smb2_find_context_vals(req,
2465                                 SMB2_CREATE_TIMEWARP_REQUEST);
2466                 if (IS_ERR(context)) {
2467                         rc = check_context_err(context,
2468                                 SMB2_CREATE_TIMEWARP_REQUEST);
2469                         if (rc < 0)
2470                                 goto err_out1;
2471                 } else {
2472                         ksmbd_debug(SMB, "get timewarp context\n");
2473                         rc = -EBADF;
2474                         goto err_out1;
2475                 }
2476
2477                 if (tcon->posix_extensions) {
2478                         context = smb2_find_context_vals(req,
2479                                 SMB2_CREATE_TAG_POSIX);
2480                         if (IS_ERR(context)) {
2481                                 rc = check_context_err(context,
2482                                                 SMB2_CREATE_TAG_POSIX);
2483                                 if (rc < 0)
2484                                         goto err_out1;
2485                         } else {
2486                                 struct create_posix *posix =
2487                                         (struct create_posix *)context;
2488                                 ksmbd_debug(SMB, "get posix context\n");
2489
2490                                 posix_mode = le32_to_cpu(posix->Mode);
2491                                 posix_ctxt = 1;
2492                         }
2493                 }
2494         }
2495
2496         if (ksmbd_override_fsids(work)) {
2497                 rc = -ENOMEM;
2498                 goto err_out1;
2499         }
2500
2501         if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
2502                 /*
2503                  * On delete request, instead of following up, need to
2504                  * look the current entity
2505                  */
2506                 rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2507                 if (!rc) {
2508                         /*
2509                          * If file exists with under flags, return access
2510                          * denied error.
2511                          */
2512                         if (req->CreateDisposition == FILE_OVERWRITE_IF_LE ||
2513                             req->CreateDisposition == FILE_OPEN_IF_LE) {
2514                                 rc = -EACCES;
2515                                 path_put(&path);
2516                                 goto err_out;
2517                         }
2518
2519                         if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
2520                                 ksmbd_debug(SMB,
2521                                         "User does not have write permission\n");
2522                                 rc = -EACCES;
2523                                 path_put(&path);
2524                                 goto err_out;
2525                         }
2526                 }
2527         } else {
2528                 if (test_share_config_flag(work->tcon->share_conf,
2529                                            KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS)) {
2530                         /*
2531                          * Use LOOKUP_FOLLOW to follow the path of
2532                          * symlink in path buildup
2533                          */
2534                         rc = ksmbd_vfs_kern_path(name, LOOKUP_FOLLOW, &path, 1);
2535                         if (rc) { /* Case for broken link ?*/
2536                                 rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2537                         }
2538                 } else {
2539                         rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2540                         if (!rc && d_is_symlink(path.dentry)) {
2541                                 rc = -EACCES;
2542                                 path_put(&path);
2543                                 goto err_out;
2544                         }
2545                 }
2546         }
2547
2548         if (rc) {
2549                 if (rc == -EACCES) {
2550                         ksmbd_debug(SMB,
2551                                 "User does not have right permission\n");
2552                         goto err_out;
2553                 }
2554                 ksmbd_debug(SMB, "can not get linux path for %s, rc = %d\n",
2555                                 name, rc);
2556                 rc = 0;
2557         } else {
2558                 file_present = true;
2559                 generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat);
2560         }
2561         if (stream_name) {
2562                 if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
2563                         if (s_type == DATA_STREAM) {
2564                                 rc = -EIO;
2565                                 rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
2566                         }
2567                 } else {
2568                         if (S_ISDIR(stat.mode) && s_type == DATA_STREAM) {
2569                                 rc = -EIO;
2570                                 rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
2571                         }
2572                 }
2573
2574                 if (req->CreateOptions & FILE_DIRECTORY_FILE_LE &&
2575                     req->FileAttributes & ATTR_NORMAL_LE) {
2576                         rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
2577                         rc = -EIO;
2578                 }
2579
2580                 if (rc < 0)
2581                         goto err_out;
2582         }
2583
2584         if (file_present && req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE &&
2585             S_ISDIR(stat.mode) && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
2586                 ksmbd_debug(SMB, "open() argument is a directory: %s, %x\n",
2587                               name, req->CreateOptions);
2588                 rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
2589                 rc = -EIO;
2590                 goto err_out;
2591         }
2592
2593         if (file_present && (req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
2594             !(req->CreateDisposition == FILE_CREATE_LE) &&
2595             !S_ISDIR(stat.mode)) {
2596                 rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
2597                 rc = -EIO;
2598                 goto err_out;
2599         }
2600
2601         if (!stream_name && file_present &&
2602             req->CreateDisposition == FILE_CREATE_LE) {
2603                 rc = -EEXIST;
2604                 goto err_out;
2605         }
2606
2607         daccess = smb_map_generic_desired_access(req->DesiredAccess);
2608
2609         if (file_present && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
2610                 rc = smb_check_perm_dacl(conn, path.dentry, &daccess,
2611                                 sess->user->uid);
2612                 if (rc)
2613                         goto err_out;
2614         }
2615
2616         if (daccess & FILE_MAXIMAL_ACCESS_LE) {
2617                 if (!file_present) {
2618                         daccess = cpu_to_le32(GENERIC_ALL_FLAGS);
2619                 } else {
2620                         rc = ksmbd_vfs_query_maximal_access(path.dentry,
2621                                                             &daccess);
2622                         if (rc)
2623                                 goto err_out;
2624                         already_permitted = true;
2625                 }
2626                 maximal_access = daccess;
2627         }
2628
2629         open_flags = smb2_create_open_flags(file_present,
2630                 daccess, req->CreateDisposition);
2631
2632         if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
2633                 if (open_flags & O_CREAT) {
2634                         ksmbd_debug(SMB,
2635                                 "User does not have write permission\n");
2636                         rc = -EACCES;
2637                         goto err_out;
2638                 }
2639         }
2640
2641         /*create file if not present */
2642         if (!file_present) {
2643                 rc = smb2_creat(work, &path, name, open_flags, posix_mode,
2644                         req->CreateOptions & FILE_DIRECTORY_FILE_LE);
2645                 if (rc)
2646                         goto err_out;
2647
2648                 created = true;
2649                 if (ea_buf) {
2650                         rc = smb2_set_ea(&ea_buf->ea, &path);
2651                         if (rc == -EOPNOTSUPP)
2652                                 rc = 0;
2653                         else if (rc)
2654                                 goto err_out;
2655                 }
2656         } else if (!already_permitted) {
2657                 bool may_delete;
2658
2659                 may_delete = daccess & FILE_DELETE_LE ||
2660                         req->CreateOptions & FILE_DELETE_ON_CLOSE_LE;
2661
2662                 /* FILE_READ_ATTRIBUTE is allowed without inode_permission,
2663                  * because execute(search) permission on a parent directory,
2664                  * is already granted.
2665                  */
2666                 if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) {
2667                         rc = ksmbd_vfs_inode_permission(path.dentry,
2668                                         open_flags & O_ACCMODE, may_delete);
2669                         if (rc)
2670                                 goto err_out;
2671                 }
2672         }
2673
2674         rc = ksmbd_query_inode_status(d_inode(path.dentry->d_parent));
2675         if (rc == KSMBD_INODE_STATUS_PENDING_DELETE) {
2676                 rc = -EBUSY;
2677                 goto err_out;
2678         }
2679
2680         rc = 0;
2681         filp = dentry_open(&path, open_flags, current_cred());
2682         if (IS_ERR(filp)) {
2683                 rc = PTR_ERR(filp);
2684                 ksmbd_err("dentry open for dir failed, rc %d\n", rc);
2685                 goto err_out;
2686         }
2687
2688         if (file_present) {
2689                 if (!(open_flags & O_TRUNC))
2690                         file_info = FILE_OPENED;
2691                 else
2692                         file_info = FILE_OVERWRITTEN;
2693
2694                 if ((req->CreateDisposition & FILE_CREATE_MASK_LE)
2695                                 == FILE_SUPERSEDE_LE)
2696                         file_info = FILE_SUPERSEDED;
2697         } else if (open_flags & O_CREAT) {
2698                 file_info = FILE_CREATED;
2699         }
2700
2701         ksmbd_vfs_set_fadvise(filp, req->CreateOptions);
2702
2703         /* Obtain Volatile-ID */
2704         fp = ksmbd_open_fd(work, filp);
2705         if (IS_ERR(fp)) {
2706                 fput(filp);
2707                 rc = PTR_ERR(fp);
2708                 fp = NULL;
2709                 goto err_out;
2710         }
2711
2712         /* Get Persistent-ID */
2713         ksmbd_open_durable_fd(fp);
2714         if (!HAS_FILE_ID(fp->persistent_id)) {
2715                 rc = -ENOMEM;
2716                 goto err_out;
2717         }
2718
2719         fp->filename = name;
2720         fp->cdoption = req->CreateDisposition;
2721         fp->daccess = daccess;
2722         fp->saccess = req->ShareAccess;
2723         fp->coption = req->CreateOptions;
2724
2725         /* Set default windows and posix acls if creating new file */
2726         if (created) {
2727                 int posix_acl_rc;
2728                 struct inode *inode = d_inode(path.dentry);
2729
2730                 posix_acl_rc = ksmbd_vfs_inherit_posix_acl(inode, d_inode(path.dentry->d_parent));
2731                 if (posix_acl_rc)
2732                         ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc);
2733
2734                 if (test_share_config_flag(work->tcon->share_conf,
2735                                            KSMBD_SHARE_FLAG_ACL_XATTR)) {
2736                         rc = smb_inherit_dacl(conn, path.dentry, sess->user->uid,
2737                                         sess->user->gid);
2738                 }
2739
2740                 if (rc) {
2741                         rc = smb2_create_sd_buffer(work, req, path.dentry);
2742                         if (rc) {
2743                                 if (posix_acl_rc)
2744                                         ksmbd_vfs_set_init_posix_acl(inode);
2745
2746                                 if (test_share_config_flag(work->tcon->share_conf,
2747                                                            KSMBD_SHARE_FLAG_ACL_XATTR)) {
2748                                         struct smb_fattr fattr;
2749                                         struct smb_ntsd *pntsd;
2750                                         int pntsd_size, ace_num = 0;
2751
2752                                         ksmbd_acls_fattr(&fattr, inode);
2753                                         if (fattr.cf_acls)
2754                                                 ace_num = fattr.cf_acls->a_count;
2755                                         if (fattr.cf_dacls)
2756                                                 ace_num += fattr.cf_dacls->a_count;
2757
2758                                         pntsd = kmalloc(sizeof(struct smb_ntsd) +
2759                                                         sizeof(struct smb_sid) * 3 +
2760                                                         sizeof(struct smb_acl) +
2761                                                         sizeof(struct smb_ace) * ace_num * 2,
2762                                                         GFP_KERNEL);
2763                                         if (!pntsd)
2764                                                 goto err_out;
2765
2766                                         rc = build_sec_desc(pntsd, NULL,
2767                                                 OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO,
2768                                                 &pntsd_size, &fattr);
2769                                         posix_acl_release(fattr.cf_acls);
2770                                         posix_acl_release(fattr.cf_dacls);
2771
2772                                         rc = ksmbd_vfs_set_sd_xattr(conn,
2773                                                 path.dentry, pntsd, pntsd_size);
2774                                         kfree(pntsd);
2775                                         if (rc)
2776                                                 ksmbd_err("failed to store ntacl in xattr : %d\n",
2777                                                                 rc);
2778                                 }
2779                         }
2780                 }
2781                 rc = 0;
2782         }
2783
2784         if (stream_name) {
2785                 rc = smb2_set_stream_name_xattr(&path,
2786                                                 fp,
2787                                                 stream_name,
2788                                                 s_type);
2789                 if (rc)
2790                         goto err_out;
2791                 file_info = FILE_CREATED;
2792         }
2793
2794         fp->attrib_only = !(req->DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE |
2795                         FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE));
2796         if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC &&
2797             !fp->attrib_only && !stream_name) {
2798                 smb_break_all_oplock(work, fp);
2799                 need_truncate = 1;
2800         }
2801
2802         /* fp should be searchable through ksmbd_inode.m_fp_list
2803          * after daccess, saccess, attrib_only, and stream are
2804          * initialized.
2805          */
2806         write_lock(&fp->f_ci->m_lock);
2807         list_add(&fp->node, &fp->f_ci->m_fp_list);
2808         write_unlock(&fp->f_ci->m_lock);
2809
2810         rc = ksmbd_vfs_getattr(&path, &stat);
2811         if (rc) {
2812                 generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat);
2813                 rc = 0;
2814         }
2815
2816         /* Check delete pending among previous fp before oplock break */
2817         if (ksmbd_inode_pending_delete(fp)) {
2818                 rc = -EBUSY;
2819                 goto err_out;
2820         }
2821
2822         share_ret = ksmbd_smb_check_shared_mode(fp->filp, fp);
2823         if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) ||
2824             (req_op_level == SMB2_OPLOCK_LEVEL_LEASE &&
2825              !(conn->vals->capabilities & SMB2_GLOBAL_CAP_LEASING))) {
2826                 if (share_ret < 0 && !S_ISDIR(FP_INODE(fp)->i_mode)) {
2827                         rc = share_ret;
2828                         goto err_out;
2829                 }
2830         } else {
2831                 if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) {
2832                         req_op_level = smb2_map_lease_to_oplock(lc->req_state);
2833                         ksmbd_debug(SMB,
2834                                 "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n",
2835                                         name, req_op_level, lc->req_state);
2836                         rc = find_same_lease_key(sess, fp->f_ci, lc);
2837                         if (rc)
2838                                 goto err_out;
2839                 } else if (open_flags == O_RDONLY &&
2840                            (req_op_level == SMB2_OPLOCK_LEVEL_BATCH ||
2841                             req_op_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE))
2842                         req_op_level = SMB2_OPLOCK_LEVEL_II;
2843
2844                 rc = smb_grant_oplock(work, req_op_level,
2845                                       fp->persistent_id, fp,
2846                                       le32_to_cpu(req->hdr.Id.SyncId.TreeId),
2847                                       lc, share_ret);
2848                 if (rc < 0)
2849                         goto err_out;
2850         }
2851
2852         if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)
2853                 ksmbd_fd_set_delete_on_close(fp, file_info);
2854
2855         if (need_truncate) {
2856                 rc = smb2_create_truncate(&path);
2857                 if (rc)
2858                         goto err_out;
2859         }
2860
2861         if (req->CreateContextsOffset) {
2862                 struct create_alloc_size_req *az_req;
2863
2864                 az_req = (struct create_alloc_size_req *)
2865                                 smb2_find_context_vals(req,
2866                                 SMB2_CREATE_ALLOCATION_SIZE);
2867                 if (IS_ERR(az_req)) {
2868                         rc = check_context_err(az_req,
2869                                 SMB2_CREATE_ALLOCATION_SIZE);
2870                         if (rc < 0)
2871                                 goto err_out;
2872                 } else {
2873                         loff_t alloc_size = le64_to_cpu(az_req->AllocationSize);
2874                         int err;
2875
2876                         ksmbd_debug(SMB,
2877                                 "request smb2 create allocate size : %llu\n",
2878                                 alloc_size);
2879                         err = ksmbd_vfs_alloc_size(work, fp, alloc_size);
2880                         if (err < 0)
2881                                 ksmbd_debug(SMB,
2882                                         "ksmbd_vfs_alloc_size is failed : %d\n",
2883                                         err);
2884                 }
2885
2886                 context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID);
2887                 if (IS_ERR(context)) {
2888                         rc = check_context_err(context, SMB2_CREATE_QUERY_ON_DISK_ID);
2889                         if (rc < 0)
2890                                 goto err_out;
2891                 } else {
2892                         ksmbd_debug(SMB, "get query on disk id context\n");
2893                         query_disk_id = 1;
2894                 }
2895         }
2896
2897         if (stat.result_mask & STATX_BTIME)
2898                 fp->create_time = ksmbd_UnixTimeToNT(stat.btime);
2899         else
2900                 fp->create_time = ksmbd_UnixTimeToNT(stat.ctime);
2901         if (req->FileAttributes || fp->f_ci->m_fattr == 0)
2902                 fp->f_ci->m_fattr = cpu_to_le32(smb2_get_dos_mode(&stat,
2903                         le32_to_cpu(req->FileAttributes)));
2904
2905         if (!created)
2906                 smb2_update_xattrs(tcon, &path, fp);
2907         else
2908                 smb2_new_xattrs(tcon, &path, fp);
2909
2910         memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
2911
2912         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
2913
2914         rsp->StructureSize = cpu_to_le16(89);
2915         rcu_read_lock();
2916         opinfo = rcu_dereference(fp->f_opinfo);
2917         rsp->OplockLevel = opinfo != NULL ? opinfo->level : 0;
2918         rcu_read_unlock();
2919         rsp->Reserved = 0;
2920         rsp->CreateAction = cpu_to_le32(file_info);
2921         rsp->CreationTime = cpu_to_le64(fp->create_time);
2922         time = ksmbd_UnixTimeToNT(stat.atime);
2923         rsp->LastAccessTime = cpu_to_le64(time);
2924         time = ksmbd_UnixTimeToNT(stat.mtime);
2925         rsp->LastWriteTime = cpu_to_le64(time);
2926         time = ksmbd_UnixTimeToNT(stat.ctime);
2927         rsp->ChangeTime = cpu_to_le64(time);
2928         rsp->AllocationSize = S_ISDIR(stat.mode) ? 0 :
2929                 cpu_to_le64(stat.blocks << 9);
2930         rsp->EndofFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
2931         rsp->FileAttributes = fp->f_ci->m_fattr;
2932
2933         rsp->Reserved2 = 0;
2934
2935         rsp->PersistentFileId = cpu_to_le64(fp->persistent_id);
2936         rsp->VolatileFileId = cpu_to_le64(fp->volatile_id);
2937
2938         rsp->CreateContextsOffset = 0;
2939         rsp->CreateContextsLength = 0;
2940         inc_rfc1001_len(rsp_org, 88); /* StructureSize - 1*/
2941
2942         /* If lease is request send lease context response */
2943         if (opinfo && opinfo->is_lease) {
2944                 struct create_context *lease_ccontext;
2945
2946                 ksmbd_debug(SMB, "lease granted on(%s) lease state 0x%x\n",
2947                                 name, opinfo->o_lease->state);
2948                 rsp->OplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
2949
2950                 lease_ccontext = (struct create_context *)rsp->Buffer;
2951                 contxt_cnt++;
2952                 create_lease_buf(rsp->Buffer, opinfo->o_lease);
2953                 le32_add_cpu(&rsp->CreateContextsLength,
2954                              conn->vals->create_lease_size);
2955                 inc_rfc1001_len(rsp_org, conn->vals->create_lease_size);
2956                 next_ptr = &lease_ccontext->Next;
2957                 next_off = conn->vals->create_lease_size;
2958         }
2959
2960         if (maximal_access_ctxt) {
2961                 struct create_context *mxac_ccontext;
2962
2963                 if (maximal_access == 0)
2964                         ksmbd_vfs_query_maximal_access(path.dentry,
2965                                                        &maximal_access);
2966                 mxac_ccontext = (struct create_context *)(rsp->Buffer +
2967                                 le32_to_cpu(rsp->CreateContextsLength));
2968                 contxt_cnt++;
2969                 create_mxac_rsp_buf(rsp->Buffer +
2970                                 le32_to_cpu(rsp->CreateContextsLength),
2971                                 le32_to_cpu(maximal_access));
2972                 le32_add_cpu(&rsp->CreateContextsLength,
2973                              conn->vals->create_mxac_size);
2974                 inc_rfc1001_len(rsp_org, conn->vals->create_mxac_size);
2975                 if (next_ptr)
2976                         *next_ptr = cpu_to_le32(next_off);
2977                 next_ptr = &mxac_ccontext->Next;
2978                 next_off = conn->vals->create_mxac_size;
2979         }
2980
2981         if (query_disk_id) {
2982                 struct create_context *disk_id_ccontext;
2983
2984                 disk_id_ccontext = (struct create_context *)(rsp->Buffer +
2985                                 le32_to_cpu(rsp->CreateContextsLength));
2986                 contxt_cnt++;
2987                 create_disk_id_rsp_buf(rsp->Buffer +
2988                                 le32_to_cpu(rsp->CreateContextsLength),
2989                                 stat.ino, tcon->id);
2990                 le32_add_cpu(&rsp->CreateContextsLength,
2991                              conn->vals->create_disk_id_size);
2992                 inc_rfc1001_len(rsp_org, conn->vals->create_disk_id_size);
2993                 if (next_ptr)
2994                         *next_ptr = cpu_to_le32(next_off);
2995                 next_ptr = &disk_id_ccontext->Next;
2996                 next_off = conn->vals->create_disk_id_size;
2997         }
2998
2999         if (posix_ctxt) {
3000                 contxt_cnt++;
3001                 create_posix_rsp_buf(rsp->Buffer +
3002                                 le32_to_cpu(rsp->CreateContextsLength),
3003                                 fp);
3004                 le32_add_cpu(&rsp->CreateContextsLength,
3005                              conn->vals->create_posix_size);
3006                 inc_rfc1001_len(rsp_org, conn->vals->create_posix_size);
3007                 if (next_ptr)
3008                         *next_ptr = cpu_to_le32(next_off);
3009         }
3010
3011         if (contxt_cnt > 0) {
3012                 rsp->CreateContextsOffset =
3013                         cpu_to_le32(offsetof(struct smb2_create_rsp, Buffer)
3014                         - 4);
3015         }
3016
3017 err_out:
3018         if (file_present || created)
3019                 path_put(&path);
3020         ksmbd_revert_fsids(work);
3021 err_out1:
3022         if (rc) {
3023                 if (rc == -EINVAL)
3024                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
3025                 else if (rc == -EOPNOTSUPP)
3026                         rsp->hdr.Status = STATUS_NOT_SUPPORTED;
3027                 else if (rc == -EACCES || rc == -ESTALE)
3028                         rsp->hdr.Status = STATUS_ACCESS_DENIED;
3029                 else if (rc == -ENOENT)
3030                         rsp->hdr.Status = STATUS_OBJECT_NAME_INVALID;
3031                 else if (rc == -EPERM)
3032                         rsp->hdr.Status = STATUS_SHARING_VIOLATION;
3033                 else if (rc == -EBUSY)
3034                         rsp->hdr.Status = STATUS_DELETE_PENDING;
3035                 else if (rc == -EBADF)
3036                         rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
3037                 else if (rc == -ENOEXEC)
3038                         rsp->hdr.Status = STATUS_DUPLICATE_OBJECTID;
3039                 else if (rc == -ENXIO)
3040                         rsp->hdr.Status = STATUS_NO_SUCH_DEVICE;
3041                 else if (rc == -EEXIST)
3042                         rsp->hdr.Status = STATUS_OBJECT_NAME_COLLISION;
3043                 else if (rc == -EMFILE)
3044                         rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
3045                 if (!rsp->hdr.Status)
3046                         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
3047
3048                 if (!fp || !fp->filename)
3049                         kfree(name);
3050                 if (fp)
3051                         ksmbd_fd_put(work, fp);
3052                 smb2_set_err_rsp(work);
3053                 ksmbd_debug(SMB, "Error response: %x\n", rsp->hdr.Status);
3054         }
3055
3056         kfree(lc);
3057
3058         return 0;
3059 }
3060
3061 static int readdir_info_level_struct_sz(int info_level)
3062 {
3063         switch (info_level) {
3064         case FILE_FULL_DIRECTORY_INFORMATION:
3065                 return sizeof(struct file_full_directory_info);
3066         case FILE_BOTH_DIRECTORY_INFORMATION:
3067                 return sizeof(struct file_both_directory_info);
3068         case FILE_DIRECTORY_INFORMATION:
3069                 return sizeof(struct file_directory_info);
3070         case FILE_NAMES_INFORMATION:
3071                 return sizeof(struct file_names_info);
3072         case FILEID_FULL_DIRECTORY_INFORMATION:
3073                 return sizeof(struct file_id_full_dir_info);
3074         case FILEID_BOTH_DIRECTORY_INFORMATION:
3075                 return sizeof(struct file_id_both_directory_info);
3076         case SMB_FIND_FILE_POSIX_INFO:
3077                 return sizeof(struct smb2_posix_info);
3078         default:
3079                 return -EOPNOTSUPP;
3080         }
3081 }
3082
3083 static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
3084 {
3085         switch (info_level) {
3086         case FILE_FULL_DIRECTORY_INFORMATION:
3087         {
3088                 struct file_full_directory_info *ffdinfo;
3089
3090                 ffdinfo = (struct file_full_directory_info *)d_info->rptr;
3091                 d_info->rptr += le32_to_cpu(ffdinfo->NextEntryOffset);
3092                 d_info->name = ffdinfo->FileName;
3093                 d_info->name_len = le32_to_cpu(ffdinfo->FileNameLength);
3094                 return 0;
3095         }
3096         case FILE_BOTH_DIRECTORY_INFORMATION:
3097         {
3098                 struct file_both_directory_info *fbdinfo;
3099
3100                 fbdinfo = (struct file_both_directory_info *)d_info->rptr;
3101                 d_info->rptr += le32_to_cpu(fbdinfo->NextEntryOffset);
3102                 d_info->name = fbdinfo->FileName;
3103                 d_info->name_len = le32_to_cpu(fbdinfo->FileNameLength);
3104                 return 0;
3105         }
3106         case FILE_DIRECTORY_INFORMATION:
3107         {
3108                 struct file_directory_info *fdinfo;
3109
3110                 fdinfo = (struct file_directory_info *)d_info->rptr;
3111                 d_info->rptr += le32_to_cpu(fdinfo->NextEntryOffset);
3112                 d_info->name = fdinfo->FileName;
3113                 d_info->name_len = le32_to_cpu(fdinfo->FileNameLength);
3114                 return 0;
3115         }
3116         case FILE_NAMES_INFORMATION:
3117         {
3118                 struct file_names_info *fninfo;
3119
3120                 fninfo = (struct file_names_info *)d_info->rptr;
3121                 d_info->rptr += le32_to_cpu(fninfo->NextEntryOffset);
3122                 d_info->name = fninfo->FileName;
3123                 d_info->name_len = le32_to_cpu(fninfo->FileNameLength);
3124                 return 0;
3125         }
3126         case FILEID_FULL_DIRECTORY_INFORMATION:
3127         {
3128                 struct file_id_full_dir_info *dinfo;
3129
3130                 dinfo = (struct file_id_full_dir_info *)d_info->rptr;
3131                 d_info->rptr += le32_to_cpu(dinfo->NextEntryOffset);
3132                 d_info->name = dinfo->FileName;
3133                 d_info->name_len = le32_to_cpu(dinfo->FileNameLength);
3134                 return 0;
3135         }
3136         case FILEID_BOTH_DIRECTORY_INFORMATION:
3137         {
3138                 struct file_id_both_directory_info *fibdinfo;
3139
3140                 fibdinfo = (struct file_id_both_directory_info *)d_info->rptr;
3141                 d_info->rptr += le32_to_cpu(fibdinfo->NextEntryOffset);
3142                 d_info->name = fibdinfo->FileName;
3143                 d_info->name_len = le32_to_cpu(fibdinfo->FileNameLength);
3144                 return 0;
3145         }
3146         case SMB_FIND_FILE_POSIX_INFO:
3147         {
3148                 struct smb2_posix_info *posix_info;
3149
3150                 posix_info = (struct smb2_posix_info *)d_info->rptr;
3151                 d_info->rptr += le32_to_cpu(posix_info->NextEntryOffset);
3152                 d_info->name = posix_info->name;
3153                 d_info->name_len = le32_to_cpu(posix_info->name_len);
3154                 return 0;
3155         }
3156         default:
3157                 return -EINVAL;
3158         }
3159 }
3160
3161 /**
3162  * smb2_populate_readdir_entry() - encode directory entry in smb2 response
3163  * buffer
3164  * @conn:       connection instance
3165  * @info_level: smb information level
3166  * @d_info:     structure included variables for query dir
3167  * @ksmbd_kstat:        ksmbd wrapper of dirent stat information
3168  *
3169  * if directory has many entries, find first can't read it fully.
3170  * find next might be called multiple times to read remaining dir entries
3171  *
3172  * Return:      0 on success, otherwise error
3173  */
3174 static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
3175                 struct ksmbd_dir_info *d_info, struct ksmbd_kstat *ksmbd_kstat)
3176 {
3177         int next_entry_offset = 0;
3178         char *conv_name;
3179         int conv_len;
3180         void *kstat;
3181         int struct_sz;
3182
3183         conv_name = ksmbd_convert_dir_info_name(d_info,
3184                                                 conn->local_nls,
3185                                                 &conv_len);
3186         if (!conv_name)
3187                 return -ENOMEM;
3188
3189         /* Somehow the name has only terminating NULL bytes */
3190         if (conv_len < 0) {
3191                 kfree(conv_name);
3192                 return -EINVAL;
3193         }
3194
3195         struct_sz = readdir_info_level_struct_sz(info_level);
3196         next_entry_offset = ALIGN(struct_sz - 1 + conv_len,
3197                                   KSMBD_DIR_INFO_ALIGNMENT);
3198
3199         if (next_entry_offset > d_info->out_buf_len) {
3200                 d_info->out_buf_len = 0;
3201                 return -ENOSPC;
3202         }
3203
3204         kstat = d_info->wptr;
3205         if (info_level != FILE_NAMES_INFORMATION)
3206                 kstat = ksmbd_vfs_init_kstat(&d_info->wptr, ksmbd_kstat);
3207
3208         switch (info_level) {
3209         case FILE_FULL_DIRECTORY_INFORMATION:
3210         {
3211                 struct file_full_directory_info *ffdinfo;
3212
3213                 ffdinfo = (struct file_full_directory_info *)kstat;
3214                 ffdinfo->FileNameLength = cpu_to_le32(conv_len);
3215                 ffdinfo->EaSize =
3216                         smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3217                 if (ffdinfo->EaSize)
3218                         ffdinfo->ExtFileAttributes = ATTR_REPARSE_POINT_LE;
3219                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3220                         ffdinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3221                 memcpy(ffdinfo->FileName, conv_name, conv_len);
3222                 ffdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3223                 break;
3224         }
3225         case FILE_BOTH_DIRECTORY_INFORMATION:
3226         {
3227                 struct file_both_directory_info *fbdinfo;
3228
3229                 fbdinfo = (struct file_both_directory_info *)kstat;
3230                 fbdinfo->FileNameLength = cpu_to_le32(conv_len);
3231                 fbdinfo->EaSize =
3232                         smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3233                 if (fbdinfo->EaSize)
3234                         fbdinfo->ExtFileAttributes = ATTR_REPARSE_POINT_LE;
3235                 fbdinfo->ShortNameLength = 0;
3236                 fbdinfo->Reserved = 0;
3237                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3238                         fbdinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3239                 memcpy(fbdinfo->FileName, conv_name, conv_len);
3240                 fbdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3241                 break;
3242         }
3243         case FILE_DIRECTORY_INFORMATION:
3244         {
3245                 struct file_directory_info *fdinfo;
3246
3247                 fdinfo = (struct file_directory_info *)kstat;
3248                 fdinfo->FileNameLength = cpu_to_le32(conv_len);
3249                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3250                         fdinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3251                 memcpy(fdinfo->FileName, conv_name, conv_len);
3252                 fdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3253                 break;
3254         }
3255         case FILE_NAMES_INFORMATION:
3256         {
3257                 struct file_names_info *fninfo;
3258
3259                 fninfo = (struct file_names_info *)kstat;
3260                 fninfo->FileNameLength = cpu_to_le32(conv_len);
3261                 memcpy(fninfo->FileName, conv_name, conv_len);
3262                 fninfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3263                 break;
3264         }
3265         case FILEID_FULL_DIRECTORY_INFORMATION:
3266         {
3267                 struct file_id_full_dir_info *dinfo;
3268
3269                 dinfo = (struct file_id_full_dir_info *)kstat;
3270                 dinfo->FileNameLength = cpu_to_le32(conv_len);
3271                 dinfo->EaSize =
3272                         smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3273                 if (dinfo->EaSize)
3274                         dinfo->ExtFileAttributes = ATTR_REPARSE_POINT_LE;
3275                 dinfo->Reserved = 0;
3276                 dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
3277                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3278                         dinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3279                 memcpy(dinfo->FileName, conv_name, conv_len);
3280                 dinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3281                 break;
3282         }
3283         case FILEID_BOTH_DIRECTORY_INFORMATION:
3284         {
3285                 struct file_id_both_directory_info *fibdinfo;
3286
3287                 fibdinfo = (struct file_id_both_directory_info *)kstat;
3288                 fibdinfo->FileNameLength = cpu_to_le32(conv_len);
3289                 fibdinfo->EaSize =
3290                         smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3291                 if (fibdinfo->EaSize)
3292                         fibdinfo->ExtFileAttributes = ATTR_REPARSE_POINT_LE;
3293                 fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
3294                 fibdinfo->ShortNameLength = 0;
3295                 fibdinfo->Reserved = 0;
3296                 fibdinfo->Reserved2 = cpu_to_le16(0);
3297                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3298                         fibdinfo->ExtFileAttributes |= ATTR_HIDDEN_LE;
3299                 memcpy(fibdinfo->FileName, conv_name, conv_len);
3300                 fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3301                 break;
3302         }
3303         case SMB_FIND_FILE_POSIX_INFO:
3304         {
3305                 struct smb2_posix_info *posix_info;
3306                 u64 time;
3307
3308                 posix_info = (struct smb2_posix_info *)kstat;
3309                 posix_info->Ignored = 0;
3310                 posix_info->CreationTime = cpu_to_le64(ksmbd_kstat->create_time);
3311                 time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->ctime);
3312                 posix_info->ChangeTime = cpu_to_le64(time);
3313                 time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->atime);
3314                 posix_info->LastAccessTime = cpu_to_le64(time);
3315                 time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->mtime);
3316                 posix_info->LastWriteTime = cpu_to_le64(time);
3317                 posix_info->EndOfFile = cpu_to_le64(ksmbd_kstat->kstat->size);
3318                 posix_info->AllocationSize = cpu_to_le64(ksmbd_kstat->kstat->blocks << 9);
3319                 posix_info->DeviceId = cpu_to_le32(ksmbd_kstat->kstat->rdev);
3320                 posix_info->HardLinks = cpu_to_le32(ksmbd_kstat->kstat->nlink);
3321                 posix_info->Mode = cpu_to_le32(ksmbd_kstat->kstat->mode);
3322                 posix_info->Inode = cpu_to_le64(ksmbd_kstat->kstat->ino);
3323                 posix_info->DosAttributes =
3324                         S_ISDIR(ksmbd_kstat->kstat->mode) ? ATTR_DIRECTORY_LE : ATTR_ARCHIVE_LE;
3325                 if (d_info->hide_dot_file && d_info->name[0] == '.')
3326                         posix_info->DosAttributes |= ATTR_HIDDEN_LE;
3327                 id_to_sid(from_kuid(&init_user_ns, ksmbd_kstat->kstat->uid),
3328                                 SIDNFS_USER, (struct smb_sid *)&posix_info->SidBuffer[0]);
3329                 id_to_sid(from_kgid(&init_user_ns, ksmbd_kstat->kstat->gid),
3330                                 SIDNFS_GROUP, (struct smb_sid *)&posix_info->SidBuffer[20]);
3331                 memcpy(posix_info->name, conv_name, conv_len);
3332                 posix_info->name_len = cpu_to_le32(conv_len);
3333                 posix_info->NextEntryOffset = cpu_to_le32(next_entry_offset);
3334                 break;
3335         }
3336
3337         } /* switch (info_level) */
3338
3339         d_info->last_entry_offset = d_info->data_count;
3340         d_info->data_count += next_entry_offset;
3341         d_info->out_buf_len -= next_entry_offset;
3342         d_info->wptr += next_entry_offset;
3343         kfree(conv_name);
3344
3345         ksmbd_debug(SMB,
3346                 "info_level : %d, buf_len :%d, next_offset : %d, data_count : %d\n",
3347                 info_level, d_info->out_buf_len,
3348                 next_entry_offset, d_info->data_count);
3349
3350         return 0;
3351 }
3352
3353 struct smb2_query_dir_private {
3354         struct ksmbd_work       *work;
3355         char                    *search_pattern;
3356         struct ksmbd_file       *dir_fp;
3357
3358         struct ksmbd_dir_info   *d_info;
3359         int                     info_level;
3360 };
3361
3362 static void lock_dir(struct ksmbd_file *dir_fp)
3363 {
3364         struct dentry *dir = dir_fp->filp->f_path.dentry;
3365
3366         inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
3367 }
3368
3369 static void unlock_dir(struct ksmbd_file *dir_fp)
3370 {
3371         struct dentry *dir = dir_fp->filp->f_path.dentry;
3372
3373         inode_unlock(d_inode(dir));
3374 }
3375
3376 static int process_query_dir_entries(struct smb2_query_dir_private *priv)
3377 {
3378         struct kstat            kstat;
3379         struct ksmbd_kstat      ksmbd_kstat;
3380         int                     rc;
3381         int                     i;
3382
3383         for (i = 0; i < priv->d_info->num_entry; i++) {
3384                 struct dentry *dent;
3385
3386                 if (dentry_name(priv->d_info, priv->info_level))
3387                         return -EINVAL;
3388
3389                 lock_dir(priv->dir_fp);
3390                 dent = lookup_one_len(priv->d_info->name,
3391                                       priv->dir_fp->filp->f_path.dentry,
3392                                       priv->d_info->name_len);
3393                 unlock_dir(priv->dir_fp);
3394
3395                 if (IS_ERR(dent)) {
3396                         ksmbd_debug(SMB, "Cannot lookup `%s' [%ld]\n",
3397                                      priv->d_info->name,
3398                                      PTR_ERR(dent));
3399                         continue;
3400                 }
3401                 if (unlikely(d_is_negative(dent))) {
3402                         dput(dent);
3403                         ksmbd_debug(SMB, "Negative dentry `%s'\n",
3404                                     priv->d_info->name);
3405                         continue;
3406                 }
3407
3408                 ksmbd_kstat.kstat = &kstat;
3409                 if (priv->info_level != FILE_NAMES_INFORMATION)
3410                         ksmbd_vfs_fill_dentry_attrs(priv->work,
3411                                                     dent,
3412                                                     &ksmbd_kstat);
3413
3414                 rc = smb2_populate_readdir_entry(priv->work->conn,
3415                                                  priv->info_level,
3416                                                  priv->d_info,
3417                                                  &ksmbd_kstat);
3418                 dput(dent);
3419                 if (rc)
3420                         return rc;
3421         }
3422         return 0;
3423 }
3424
3425 static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
3426                 int info_level)
3427 {
3428         int struct_sz;
3429         int conv_len;
3430         int next_entry_offset;
3431
3432         struct_sz = readdir_info_level_struct_sz(info_level);
3433         if (struct_sz == -EOPNOTSUPP)
3434                 return -EOPNOTSUPP;
3435
3436         conv_len = (d_info->name_len + 1) * 2;
3437         next_entry_offset = ALIGN(struct_sz - 1 + conv_len,
3438                                   KSMBD_DIR_INFO_ALIGNMENT);
3439
3440         if (next_entry_offset > d_info->out_buf_len) {
3441                 d_info->out_buf_len = 0;
3442                 return -ENOSPC;
3443         }
3444
3445         switch (info_level) {
3446         case FILE_FULL_DIRECTORY_INFORMATION:
3447         {
3448                 struct file_full_directory_info *ffdinfo;
3449
3450                 ffdinfo = (struct file_full_directory_info *)d_info->wptr;
3451                 memcpy(ffdinfo->FileName, d_info->name, d_info->name_len);
3452                 ffdinfo->FileName[d_info->name_len] = 0x00;
3453                 ffdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3454                 ffdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3455                 break;
3456         }
3457         case FILE_BOTH_DIRECTORY_INFORMATION:
3458         {
3459                 struct file_both_directory_info *fbdinfo;
3460
3461                 fbdinfo = (struct file_both_directory_info *)d_info->wptr;
3462                 memcpy(fbdinfo->FileName, d_info->name, d_info->name_len);
3463                 fbdinfo->FileName[d_info->name_len] = 0x00;
3464                 fbdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3465                 fbdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3466                 break;
3467         }
3468         case FILE_DIRECTORY_INFORMATION:
3469         {
3470                 struct file_directory_info *fdinfo;
3471
3472                 fdinfo = (struct file_directory_info *)d_info->wptr;
3473                 memcpy(fdinfo->FileName, d_info->name, d_info->name_len);
3474                 fdinfo->FileName[d_info->name_len] = 0x00;
3475                 fdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3476                 fdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3477                 break;
3478         }
3479         case FILE_NAMES_INFORMATION:
3480         {
3481                 struct file_names_info *fninfo;
3482
3483                 fninfo = (struct file_names_info *)d_info->wptr;
3484                 memcpy(fninfo->FileName, d_info->name, d_info->name_len);
3485                 fninfo->FileName[d_info->name_len] = 0x00;
3486                 fninfo->FileNameLength = cpu_to_le32(d_info->name_len);
3487                 fninfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3488                 break;
3489         }
3490         case FILEID_FULL_DIRECTORY_INFORMATION:
3491         {
3492                 struct file_id_full_dir_info *dinfo;
3493
3494                 dinfo = (struct file_id_full_dir_info *)d_info->wptr;
3495                 memcpy(dinfo->FileName, d_info->name, d_info->name_len);
3496                 dinfo->FileName[d_info->name_len] = 0x00;
3497                 dinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3498                 dinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3499                 break;
3500         }
3501         case FILEID_BOTH_DIRECTORY_INFORMATION:
3502         {
3503                 struct file_id_both_directory_info *fibdinfo;
3504
3505                 fibdinfo = (struct file_id_both_directory_info *)d_info->wptr;
3506                 memcpy(fibdinfo->FileName, d_info->name, d_info->name_len);
3507                 fibdinfo->FileName[d_info->name_len] = 0x00;
3508                 fibdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
3509                 fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3510                 break;
3511         }
3512         case SMB_FIND_FILE_POSIX_INFO:
3513         {
3514                 struct smb2_posix_info *posix_info;
3515
3516                 posix_info = (struct smb2_posix_info *)d_info->wptr;
3517                 memcpy(posix_info->name, d_info->name, d_info->name_len);
3518                 posix_info->name[d_info->name_len] = 0x00;
3519                 posix_info->name_len = cpu_to_le32(d_info->name_len);
3520                 posix_info->NextEntryOffset =
3521                         cpu_to_le32(next_entry_offset);
3522                 break;
3523         }
3524         } /* switch (info_level) */
3525
3526         d_info->num_entry++;
3527         d_info->out_buf_len -= next_entry_offset;
3528         d_info->wptr += next_entry_offset;
3529         return 0;
3530 }
3531
3532 static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
3533                 loff_t offset, u64 ino, unsigned int d_type)
3534 {
3535         struct ksmbd_readdir_data       *buf;
3536         struct smb2_query_dir_private   *priv;
3537         struct ksmbd_dir_info           *d_info;
3538         int                             rc;
3539
3540         buf     = container_of(ctx, struct ksmbd_readdir_data, ctx);
3541         priv    = buf->private;
3542         d_info  = priv->d_info;
3543
3544         /* dot and dotdot entries are already reserved */
3545         if (!strcmp(".", name) || !strcmp("..", name))
3546                 return 0;
3547         if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
3548                 return 0;
3549         if (!match_pattern(name, namlen, priv->search_pattern))
3550                 return 0;
3551
3552         d_info->name            = name;
3553         d_info->name_len        = namlen;
3554         rc = reserve_populate_dentry(d_info, priv->info_level);
3555         if (rc)
3556                 return rc;
3557         if (d_info->flags & SMB2_RETURN_SINGLE_ENTRY) {
3558                 d_info->out_buf_len = 0;
3559                 return 0;
3560         }
3561         return 0;
3562 }
3563
3564 static void restart_ctx(struct dir_context *ctx)
3565 {
3566         ctx->pos = 0;
3567 }
3568
3569 static int verify_info_level(int info_level)
3570 {
3571         switch (info_level) {
3572         case FILE_FULL_DIRECTORY_INFORMATION:
3573         case FILE_BOTH_DIRECTORY_INFORMATION:
3574         case FILE_DIRECTORY_INFORMATION:
3575         case FILE_NAMES_INFORMATION:
3576         case FILEID_FULL_DIRECTORY_INFORMATION:
3577         case FILEID_BOTH_DIRECTORY_INFORMATION:
3578         case SMB_FIND_FILE_POSIX_INFO:
3579                 break;
3580         default:
3581                 return -EOPNOTSUPP;
3582         }
3583
3584         return 0;
3585 }
3586
3587 int smb2_query_dir(struct ksmbd_work *work)
3588 {
3589         struct ksmbd_conn *conn = work->conn;
3590         struct smb2_query_directory_req *req;
3591         struct smb2_query_directory_rsp *rsp, *rsp_org;
3592         struct ksmbd_share_config *share = work->tcon->share_conf;
3593         struct ksmbd_file *dir_fp = NULL;
3594         struct ksmbd_dir_info d_info;
3595         int rc = 0;
3596         char *srch_ptr = NULL;
3597         unsigned char srch_flag;
3598         int buffer_sz;
3599         struct smb2_query_dir_private query_dir_private = {NULL, };
3600
3601         rsp_org = work->response_buf;
3602         WORK_BUFFERS(work, req, rsp);
3603
3604         if (ksmbd_override_fsids(work)) {
3605                 rsp->hdr.Status = STATUS_NO_MEMORY;
3606                 smb2_set_err_rsp(work);
3607                 return -ENOMEM;
3608         }
3609
3610         rc = verify_info_level(req->FileInformationClass);
3611         if (rc) {
3612                 rc = -EFAULT;
3613                 goto err_out2;
3614         }
3615
3616         dir_fp = ksmbd_lookup_fd_slow(work,
3617                         le64_to_cpu(req->VolatileFileId),
3618                         le64_to_cpu(req->PersistentFileId));
3619         if (!dir_fp) {
3620                 rc = -EBADF;
3621                 goto err_out2;
3622         }
3623
3624         if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) ||
3625             inode_permission(&init_user_ns, file_inode(dir_fp->filp), MAY_READ | MAY_EXEC)) {
3626                 ksmbd_err("no right to enumerate directory (%s)\n",
3627                         FP_FILENAME(dir_fp));
3628                 rc = -EACCES;
3629                 goto err_out2;
3630         }
3631
3632         if (!S_ISDIR(file_inode(dir_fp->filp)->i_mode)) {
3633                 ksmbd_err("can't do query dir for a file\n");
3634                 rc = -EINVAL;
3635                 goto err_out2;
3636         }
3637
3638         srch_flag = req->Flags;
3639         srch_ptr = smb_strndup_from_utf16(req->Buffer,
3640                         le16_to_cpu(req->FileNameLength), 1,
3641                         conn->local_nls);
3642         if (IS_ERR(srch_ptr)) {
3643                 ksmbd_debug(SMB, "Search Pattern not found\n");
3644                 rc = -EINVAL;
3645                 goto err_out2;
3646         } else {
3647                 ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr);
3648         }
3649
3650         ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename);
3651
3652         if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
3653                 ksmbd_debug(SMB, "Restart directory scan\n");
3654                 generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
3655                 restart_ctx(&dir_fp->readdir_data.ctx);
3656         }
3657
3658         memset(&d_info, 0, sizeof(struct ksmbd_dir_info));
3659         d_info.wptr = (char *)rsp->Buffer;
3660         d_info.rptr = (char *)rsp->Buffer;
3661         d_info.out_buf_len = (work->response_sz - (get_rfc1002_len(rsp_org) + 4));
3662         d_info.out_buf_len = min_t(int, d_info.out_buf_len,
3663                 le32_to_cpu(req->OutputBufferLength)) - sizeof(struct smb2_query_directory_rsp);
3664         d_info.flags = srch_flag;
3665
3666         /*
3667          * reserve dot and dotdot entries in head of buffer
3668          * in first response
3669          */
3670         rc = ksmbd_populate_dot_dotdot_entries(work, req->FileInformationClass,
3671                 dir_fp, &d_info, srch_ptr, smb2_populate_readdir_entry);
3672         if (rc == -ENOSPC)
3673                 rc = 0;
3674         else if (rc)
3675                 goto err_out;
3676
3677         if (test_share_config_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES))
3678                 d_info.hide_dot_file = true;
3679
3680         buffer_sz                               = d_info.out_buf_len;
3681         d_info.rptr                             = d_info.wptr;
3682         query_dir_private.work                  = work;
3683         query_dir_private.search_pattern        = srch_ptr;
3684         query_dir_private.dir_fp                = dir_fp;
3685         query_dir_private.d_info                = &d_info;
3686         query_dir_private.info_level            = req->FileInformationClass;
3687         dir_fp->readdir_data.private            = &query_dir_private;
3688         set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir);
3689
3690         rc = ksmbd_vfs_readdir(dir_fp->filp, &dir_fp->readdir_data);
3691         if (rc == 0)
3692                 restart_ctx(&dir_fp->readdir_data.ctx);
3693         if (rc == -ENOSPC)
3694                 rc = 0;
3695         if (rc)
3696                 goto err_out;
3697
3698         d_info.wptr = d_info.rptr;
3699         d_info.out_buf_len = buffer_sz;
3700         rc = process_query_dir_entries(&query_dir_private);
3701         if (rc)
3702                 goto err_out;
3703
3704         if (!d_info.data_count && d_info.out_buf_len >= 0) {
3705                 if (srch_flag & SMB2_RETURN_SINGLE_ENTRY && !is_asterisk(srch_ptr)) {
3706                         rsp->hdr.Status = STATUS_NO_SUCH_FILE;
3707                 } else {
3708                         dir_fp->dot_dotdot[0] = dir_fp->dot_dotdot[1] = 0;
3709                         rsp->hdr.Status = STATUS_NO_MORE_FILES;
3710                 }
3711                 rsp->StructureSize = cpu_to_le16(9);
3712                 rsp->OutputBufferOffset = cpu_to_le16(0);
3713                 rsp->OutputBufferLength = cpu_to_le32(0);
3714                 rsp->Buffer[0] = 0;
3715                 inc_rfc1001_len(rsp_org, 9);
3716         } else {
3717                 ((struct file_directory_info *)
3718                 ((char *)rsp->Buffer + d_info.last_entry_offset))
3719                 ->NextEntryOffset = 0;
3720
3721                 rsp->StructureSize = cpu_to_le16(9);
3722                 rsp->OutputBufferOffset = cpu_to_le16(72);
3723                 rsp->OutputBufferLength = cpu_to_le32(d_info.data_count);
3724                 inc_rfc1001_len(rsp_org, 8 + d_info.data_count);
3725         }
3726
3727         kfree(srch_ptr);
3728         ksmbd_fd_put(work, dir_fp);
3729         ksmbd_revert_fsids(work);
3730         return 0;
3731
3732 err_out:
3733         ksmbd_err("error while processing smb2 query dir rc = %d\n", rc);
3734         kfree(srch_ptr);
3735
3736 err_out2:
3737         if (rc == -EINVAL)
3738                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
3739         else if (rc == -EACCES)
3740                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
3741         else if (rc == -ENOENT)
3742                 rsp->hdr.Status = STATUS_NO_SUCH_FILE;
3743         else if (rc == -EBADF)
3744                 rsp->hdr.Status = STATUS_FILE_CLOSED;
3745         else if (rc == -ENOMEM)
3746                 rsp->hdr.Status = STATUS_NO_MEMORY;
3747         else if (rc == -EFAULT)
3748                 rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
3749         if (!rsp->hdr.Status)
3750                 rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
3751
3752         smb2_set_err_rsp(work);
3753         ksmbd_fd_put(work, dir_fp);
3754         ksmbd_revert_fsids(work);
3755         return 0;
3756 }
3757
3758 /**
3759  * buffer_check_err() - helper function to check buffer errors
3760  * @reqOutputBufferLength:      max buffer length expected in command response
3761  * @rsp:                query info response buffer contains output buffer length
3762  * @infoclass_size:     query info class response buffer size
3763  *
3764  * Return:      0 on success, otherwise error
3765  */
3766 static int buffer_check_err(int reqOutputBufferLength,
3767                 struct smb2_query_info_rsp *rsp, int infoclass_size)
3768 {
3769         if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) {
3770                 if (reqOutputBufferLength < infoclass_size) {
3771                         ksmbd_err("Invalid Buffer Size Requested\n");
3772                         rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
3773                         rsp->hdr.smb2_buf_length = cpu_to_be32(sizeof(struct smb2_hdr) - 4);
3774                         return -EINVAL;
3775                 }
3776
3777                 ksmbd_debug(SMB, "Buffer Overflow\n");
3778                 rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
3779                 rsp->hdr.smb2_buf_length = cpu_to_be32(sizeof(struct smb2_hdr) - 4 +
3780                                 reqOutputBufferLength);
3781                 rsp->OutputBufferLength = cpu_to_le32(reqOutputBufferLength);
3782         }
3783         return 0;
3784 }
3785
3786 static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp)
3787 {
3788         struct smb2_file_standard_info *sinfo;
3789
3790         sinfo = (struct smb2_file_standard_info *)rsp->Buffer;
3791
3792         sinfo->AllocationSize = cpu_to_le64(4096);
3793         sinfo->EndOfFile = cpu_to_le64(0);
3794         sinfo->NumberOfLinks = cpu_to_le32(1);
3795         sinfo->DeletePending = 1;
3796         sinfo->Directory = 0;
3797         rsp->OutputBufferLength =
3798                 cpu_to_le32(sizeof(struct smb2_file_standard_info));
3799         inc_rfc1001_len(rsp, sizeof(struct smb2_file_standard_info));
3800 }
3801
3802 static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp,
3803                 u64 num)
3804 {
3805         struct smb2_file_internal_info *file_info;
3806
3807         file_info = (struct smb2_file_internal_info *)rsp->Buffer;
3808
3809         /* any unique number */
3810         file_info->IndexNumber = cpu_to_le64(num | (1ULL << 63));
3811         rsp->OutputBufferLength =
3812                 cpu_to_le32(sizeof(struct smb2_file_internal_info));
3813         inc_rfc1001_len(rsp, sizeof(struct smb2_file_internal_info));
3814 }
3815
3816 static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
3817                 struct smb2_query_info_req *req,
3818                 struct smb2_query_info_rsp *rsp)
3819 {
3820         u64 id;
3821         int rc;
3822
3823         /*
3824          * Windows can sometime send query file info request on
3825          * pipe without opening it, checking error condition here
3826          */
3827         id = le64_to_cpu(req->VolatileFileId);
3828         if (!ksmbd_session_rpc_method(sess, id))
3829                 return -ENOENT;
3830
3831         ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n",
3832                      req->FileInfoClass, le64_to_cpu(req->VolatileFileId));
3833
3834         switch (req->FileInfoClass) {
3835         case FILE_STANDARD_INFORMATION:
3836                 get_standard_info_pipe(rsp);
3837                 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
3838                         rsp, FILE_STANDARD_INFORMATION_SIZE);
3839                 break;
3840         case FILE_INTERNAL_INFORMATION:
3841                 get_internal_info_pipe(rsp, id);
3842                 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
3843                         rsp, FILE_INTERNAL_INFORMATION_SIZE);
3844                 break;
3845         default:
3846                 ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n",
3847                         req->FileInfoClass);
3848                 rc = -EOPNOTSUPP;
3849         }
3850         return rc;
3851 }
3852
3853 /**
3854  * smb2_get_ea() - handler for smb2 get extended attribute command
3855  * @work:       smb work containing query info command buffer
3856  * @fp:         ksmbd_file pointer
3857  * @req:        get extended attribute request
3858  * @rsp:        response buffer pointer
3859  * @rsp_org:    base response buffer pointer in case of chained response
3860  *
3861  * Return:      0 on success, otherwise error
3862  */
3863 static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
3864                 struct smb2_query_info_req *req,
3865                 struct smb2_query_info_rsp *rsp, void *rsp_org)
3866 {
3867         struct smb2_ea_info *eainfo, *prev_eainfo;
3868         char *name, *ptr, *xattr_list = NULL, *buf;
3869         int rc, name_len, value_len, xattr_list_len, idx;
3870         ssize_t buf_free_len, alignment_bytes, next_offset, rsp_data_cnt = 0;
3871         struct smb2_ea_info_req *ea_req = NULL;
3872         struct path *path;
3873
3874         if (!(fp->daccess & FILE_READ_EA_LE)) {
3875                 ksmbd_err("Not permitted to read ext attr : 0x%x\n",
3876                           fp->daccess);
3877                 return -EACCES;
3878         }
3879
3880         path = &fp->filp->f_path;
3881         /* single EA entry is requested with given user.* name */
3882         if (req->InputBufferLength) {
3883                 ea_req = (struct smb2_ea_info_req *)req->Buffer;
3884         } else {
3885                 /* need to send all EAs, if no specific EA is requested*/
3886                 if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY)
3887                         ksmbd_debug(SMB,
3888                                 "All EAs are requested but need to send single EA entry in rsp flags 0x%x\n",
3889                                 le32_to_cpu(req->Flags));
3890         }
3891
3892         buf_free_len = work->response_sz -
3893                         (get_rfc1002_len(rsp_org) + 4) -
3894                         sizeof(struct smb2_query_info_rsp);
3895
3896         if (le32_to_cpu(req->OutputBufferLength) < buf_free_len)
3897                 buf_free_len = le32_to_cpu(req->OutputBufferLength);
3898
3899         rc = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
3900         if (rc < 0) {
3901                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
3902                 goto out;
3903         } else if (!rc) { /* there is no EA in the file */
3904                 ksmbd_debug(SMB, "no ea data in the file\n");
3905                 goto done;
3906         }
3907         xattr_list_len = rc;
3908
3909         ptr = (char *)rsp->Buffer;
3910         eainfo = (struct smb2_ea_info *)ptr;
3911         prev_eainfo = eainfo;
3912         idx = 0;
3913
3914         while (idx < xattr_list_len) {
3915                 name = xattr_list + idx;
3916                 name_len = strlen(name);
3917
3918                 ksmbd_debug(SMB, "%s, len %d\n", name, name_len);
3919                 idx += name_len + 1;
3920
3921                 /*
3922                  * CIFS does not support EA other than user.* namespace,
3923                  * still keep the framework generic, to list other attrs
3924                  * in future.
3925                  */
3926                 if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
3927                         continue;
3928
3929                 if (!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
3930                              STREAM_PREFIX_LEN))
3931                         continue;
3932
3933                 if (req->InputBufferLength &&
3934                     strncmp(&name[XATTR_USER_PREFIX_LEN], ea_req->name,
3935                             ea_req->EaNameLength))
3936                         continue;
3937
3938                 if (!strncmp(&name[XATTR_USER_PREFIX_LEN],
3939                              DOS_ATTRIBUTE_PREFIX, DOS_ATTRIBUTE_PREFIX_LEN))
3940                         continue;
3941
3942                 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
3943                         name_len -= XATTR_USER_PREFIX_LEN;
3944
3945                 ptr = (char *)(&eainfo->name + name_len + 1);
3946                 buf_free_len -= (offsetof(struct smb2_ea_info, name) +
3947                                 name_len + 1);
3948                 /* bailout if xattr can't fit in buf_free_len */
3949                 value_len = ksmbd_vfs_getxattr(path->dentry, name, &buf);
3950                 if (value_len <= 0) {
3951                         rc = -ENOENT;
3952                         rsp->hdr.Status = STATUS_INVALID_HANDLE;
3953                         goto out;
3954                 }
3955
3956                 buf_free_len -= value_len;
3957                 if (buf_free_len < 0) {
3958                         kfree(buf);
3959                         break;
3960                 }
3961
3962                 memcpy(ptr, buf, value_len);
3963                 kfree(buf);
3964
3965                 ptr += value_len;
3966                 eainfo->Flags = 0;
3967                 eainfo->EaNameLength = name_len;
3968
3969                 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
3970                         memcpy(eainfo->name, &name[XATTR_USER_PREFIX_LEN],
3971                                         name_len);
3972                 else
3973                         memcpy(eainfo->name, name, name_len);
3974
3975                 eainfo->name[name_len] = '\0';
3976                 eainfo->EaValueLength = cpu_to_le16(value_len);
3977                 next_offset = offsetof(struct smb2_ea_info, name) +
3978                         name_len + 1 + value_len;
3979
3980                 /* align next xattr entry at 4 byte bundary */
3981                 alignment_bytes = ((next_offset + 3) & ~3) - next_offset;
3982                 if (alignment_bytes) {
3983                         memset(ptr, '\0', alignment_bytes);
3984                         ptr += alignment_bytes;
3985                         next_offset += alignment_bytes;
3986                         buf_free_len -= alignment_bytes;
3987                 }
3988                 eainfo->NextEntryOffset = cpu_to_le32(next_offset);
3989                 prev_eainfo = eainfo;
3990                 eainfo = (struct smb2_ea_info *)ptr;
3991                 rsp_data_cnt += next_offset;
3992
3993                 if (req->InputBufferLength) {
3994                         ksmbd_debug(SMB, "single entry requested\n");
3995                         break;
3996                 }
3997         }
3998
3999         /* no more ea entries */
4000         prev_eainfo->NextEntryOffset = 0;
4001 done:
4002         rc = 0;
4003         if (rsp_data_cnt == 0)
4004                 rsp->hdr.Status = STATUS_NO_EAS_ON_FILE;
4005         rsp->OutputBufferLength = cpu_to_le32(rsp_data_cnt);
4006         inc_rfc1001_len(rsp_org, rsp_data_cnt);
4007 out:
4008         kvfree(xattr_list);
4009         return rc;
4010 }
4011
4012 static void get_file_access_info(struct smb2_query_info_rsp *rsp,
4013                 struct ksmbd_file *fp, void *rsp_org)
4014 {
4015         struct smb2_file_access_info *file_info;
4016
4017         file_info = (struct smb2_file_access_info *)rsp->Buffer;
4018         file_info->AccessFlags = fp->daccess;
4019         rsp->OutputBufferLength =
4020                 cpu_to_le32(sizeof(struct smb2_file_access_info));
4021         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_access_info));
4022 }
4023
4024 static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
4025                 struct ksmbd_file *fp, void *rsp_org)
4026 {
4027         struct smb2_file_all_info *basic_info;
4028         struct kstat stat;
4029         u64 time;
4030
4031         if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4032                 ksmbd_err("no right to read the attributes : 0x%x\n",
4033                            fp->daccess);
4034                 return -EACCES;
4035         }
4036
4037         basic_info = (struct smb2_file_all_info *)rsp->Buffer;
4038         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
4039         basic_info->CreationTime = cpu_to_le64(fp->create_time);
4040         time = ksmbd_UnixTimeToNT(stat.atime);
4041         basic_info->LastAccessTime = cpu_to_le64(time);
4042         time = ksmbd_UnixTimeToNT(stat.mtime);
4043         basic_info->LastWriteTime = cpu_to_le64(time);
4044         time = ksmbd_UnixTimeToNT(stat.ctime);
4045         basic_info->ChangeTime = cpu_to_le64(time);
4046         basic_info->Attributes = fp->f_ci->m_fattr;
4047         basic_info->Pad1 = 0;
4048         rsp->OutputBufferLength =
4049                 cpu_to_le32(offsetof(struct smb2_file_all_info, AllocationSize));
4050         inc_rfc1001_len(rsp_org, offsetof(struct smb2_file_all_info,
4051                                           AllocationSize));
4052         return 0;
4053 }
4054
4055 static unsigned long long get_allocation_size(struct inode *inode,
4056                 struct kstat *stat)
4057 {
4058         unsigned long long alloc_size = 0;
4059
4060         if (!S_ISDIR(stat->mode)) {
4061                 if ((inode->i_blocks << 9) <= stat->size)
4062                         alloc_size = stat->size;
4063                 else
4064                         alloc_size = inode->i_blocks << 9;
4065         }
4066
4067         return alloc_size;
4068 }
4069
4070 static void get_file_standard_info(struct smb2_query_info_rsp *rsp,
4071                 struct ksmbd_file *fp, void *rsp_org)
4072 {
4073         struct smb2_file_standard_info *sinfo;
4074         unsigned int delete_pending;
4075         struct inode *inode;
4076         struct kstat stat;
4077
4078         inode = FP_INODE(fp);
4079         generic_fillattr(&init_user_ns, inode, &stat);
4080
4081         sinfo = (struct smb2_file_standard_info *)rsp->Buffer;
4082         delete_pending = ksmbd_inode_pending_delete(fp);
4083
4084         sinfo->AllocationSize = cpu_to_le64(get_allocation_size(inode, &stat));
4085         sinfo->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
4086         sinfo->NumberOfLinks = cpu_to_le32(get_nlink(&stat) - delete_pending);
4087         sinfo->DeletePending = delete_pending;
4088         sinfo->Directory = S_ISDIR(stat.mode) ? 1 : 0;
4089         rsp->OutputBufferLength =
4090                 cpu_to_le32(sizeof(struct smb2_file_standard_info));
4091         inc_rfc1001_len(rsp_org,
4092                         sizeof(struct smb2_file_standard_info));
4093 }
4094
4095 static void get_file_alignment_info(struct smb2_query_info_rsp *rsp,
4096                 void *rsp_org)
4097 {
4098         struct smb2_file_alignment_info *file_info;
4099
4100         file_info = (struct smb2_file_alignment_info *)rsp->Buffer;
4101         file_info->AlignmentRequirement = 0;
4102         rsp->OutputBufferLength =
4103                 cpu_to_le32(sizeof(struct smb2_file_alignment_info));
4104         inc_rfc1001_len(rsp_org,
4105                         sizeof(struct smb2_file_alignment_info));
4106 }
4107
4108 static int get_file_all_info(struct ksmbd_work *work,
4109                 struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
4110                 void *rsp_org)
4111 {
4112         struct ksmbd_conn *conn = work->conn;
4113         struct smb2_file_all_info *file_info;
4114         unsigned int delete_pending;
4115         struct inode *inode;
4116         struct kstat stat;
4117         int conv_len;
4118         char *filename;
4119         u64 time;
4120
4121         if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4122                 ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n",
4123                                 fp->daccess);
4124                 return -EACCES;
4125         }
4126
4127         filename = convert_to_nt_pathname(fp->filename,
4128                                           work->tcon->share_conf->path);
4129         if (!filename)
4130                 return -ENOMEM;
4131
4132         inode = FP_INODE(fp);
4133         generic_fillattr(&init_user_ns, inode, &stat);
4134
4135         ksmbd_debug(SMB, "filename = %s\n", filename);
4136         delete_pending = ksmbd_inode_pending_delete(fp);
4137         file_info = (struct smb2_file_all_info *)rsp->Buffer;
4138
4139         file_info->CreationTime = cpu_to_le64(fp->create_time);
4140         time = ksmbd_UnixTimeToNT(stat.atime);
4141         file_info->LastAccessTime = cpu_to_le64(time);
4142         time = ksmbd_UnixTimeToNT(stat.mtime);
4143         file_info->LastWriteTime = cpu_to_le64(time);
4144         time = ksmbd_UnixTimeToNT(stat.ctime);
4145         file_info->ChangeTime = cpu_to_le64(time);
4146         file_info->Attributes = fp->f_ci->m_fattr;
4147         file_info->Pad1 = 0;
4148         file_info->AllocationSize =
4149                 cpu_to_le64(get_allocation_size(inode, &stat));
4150         file_info->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
4151         file_info->NumberOfLinks =
4152                         cpu_to_le32(get_nlink(&stat) - delete_pending);
4153         file_info->DeletePending = delete_pending;
4154         file_info->Directory = S_ISDIR(stat.mode) ? 1 : 0;
4155         file_info->Pad2 = 0;
4156         file_info->IndexNumber = cpu_to_le64(stat.ino);
4157         file_info->EASize = 0;
4158         file_info->AccessFlags = fp->daccess;
4159         file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos);
4160         file_info->Mode = fp->coption;
4161         file_info->AlignmentRequirement = 0;
4162         conv_len = smbConvertToUTF16((__le16 *)file_info->FileName,
4163                                              filename,
4164                                              PATH_MAX,
4165                                              conn->local_nls,
4166                                              0);
4167         conv_len *= 2;
4168         file_info->FileNameLength = cpu_to_le32(conv_len);
4169         rsp->OutputBufferLength =
4170                 cpu_to_le32(sizeof(struct smb2_file_all_info) + conv_len - 1);
4171         kfree(filename);
4172         inc_rfc1001_len(rsp_org, le32_to_cpu(rsp->OutputBufferLength));
4173         return 0;
4174 }
4175
4176 static void get_file_alternate_info(struct ksmbd_work *work,
4177                 struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
4178                 void *rsp_org)
4179 {
4180         struct ksmbd_conn *conn = work->conn;
4181         struct smb2_file_alt_name_info *file_info;
4182         int conv_len;
4183         char *filename;
4184
4185         filename = (char *)FP_FILENAME(fp);
4186         file_info = (struct smb2_file_alt_name_info *)rsp->Buffer;
4187         conv_len = ksmbd_extract_shortname(conn,
4188                                            filename,
4189                                            file_info->FileName);
4190         file_info->FileNameLength = cpu_to_le32(conv_len);
4191         rsp->OutputBufferLength =
4192                 cpu_to_le32(sizeof(struct smb2_file_alt_name_info) + conv_len);
4193         inc_rfc1001_len(rsp_org, le32_to_cpu(rsp->OutputBufferLength));
4194 }
4195
4196 static void get_file_stream_info(struct ksmbd_work *work,
4197                 struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
4198                 void *rsp_org)
4199 {
4200         struct ksmbd_conn *conn = work->conn;
4201         struct smb2_file_stream_info *file_info;
4202         char *stream_name, *xattr_list = NULL, *stream_buf;
4203         struct kstat stat;
4204         struct path *path = &fp->filp->f_path;
4205         ssize_t xattr_list_len;
4206         int nbytes = 0, streamlen, stream_name_len, next, idx = 0;
4207
4208         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
4209         file_info = (struct smb2_file_stream_info *)rsp->Buffer;
4210
4211         xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
4212         if (xattr_list_len < 0) {
4213                 goto out;
4214         } else if (!xattr_list_len) {
4215                 ksmbd_debug(SMB, "empty xattr in the file\n");
4216                 goto out;
4217         }
4218
4219         while (idx < xattr_list_len) {
4220                 stream_name = xattr_list + idx;
4221                 streamlen = strlen(stream_name);
4222                 idx += streamlen + 1;
4223
4224                 ksmbd_debug(SMB, "%s, len %d\n", stream_name, streamlen);
4225
4226                 if (strncmp(&stream_name[XATTR_USER_PREFIX_LEN],
4227                             STREAM_PREFIX, STREAM_PREFIX_LEN))
4228                         continue;
4229
4230                 stream_name_len = streamlen - (XATTR_USER_PREFIX_LEN +
4231                                 STREAM_PREFIX_LEN);
4232                 streamlen = stream_name_len;
4233
4234                 /* plus : size */
4235                 streamlen += 1;
4236                 stream_buf = kmalloc(streamlen + 1, GFP_KERNEL);
4237                 if (!stream_buf)
4238                         break;
4239
4240                 streamlen = snprintf(stream_buf, streamlen + 1,
4241                                 ":%s", &stream_name[XATTR_NAME_STREAM_LEN]);
4242
4243                 file_info = (struct smb2_file_stream_info *)
4244                         &rsp->Buffer[nbytes];
4245                 streamlen  = smbConvertToUTF16((__le16 *)file_info->StreamName,
4246                                                 stream_buf,
4247                                                 streamlen,
4248                                                 conn->local_nls,
4249                                                 0);
4250                 streamlen *= 2;
4251                 kfree(stream_buf);
4252                 file_info->StreamNameLength = cpu_to_le32(streamlen);
4253                 file_info->StreamSize = cpu_to_le64(stream_name_len);
4254                 file_info->StreamAllocationSize = cpu_to_le64(stream_name_len);
4255
4256                 next = sizeof(struct smb2_file_stream_info) + streamlen;
4257                 nbytes += next;
4258                 file_info->NextEntryOffset = cpu_to_le32(next);
4259         }
4260
4261         if (nbytes) {
4262                 file_info = (struct smb2_file_stream_info *)
4263                         &rsp->Buffer[nbytes];
4264                 streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName,
4265                         "::$DATA", 7, conn->local_nls, 0);
4266                 streamlen *= 2;
4267                 file_info->StreamNameLength = cpu_to_le32(streamlen);
4268                 file_info->StreamSize = S_ISDIR(stat.mode) ? 0 :
4269                         cpu_to_le64(stat.size);
4270                 file_info->StreamAllocationSize = S_ISDIR(stat.mode) ? 0 :
4271                         cpu_to_le64(stat.size);
4272                 nbytes += sizeof(struct smb2_file_stream_info) + streamlen;
4273         }
4274
4275         /* last entry offset should be 0 */
4276         file_info->NextEntryOffset = 0;
4277 out:
4278         kvfree(xattr_list);
4279
4280         rsp->OutputBufferLength = cpu_to_le32(nbytes);
4281         inc_rfc1001_len(rsp_org, nbytes);
4282 }
4283
4284 static void get_file_internal_info(struct smb2_query_info_rsp *rsp,
4285                 struct ksmbd_file *fp, void *rsp_org)
4286 {
4287         struct smb2_file_internal_info *file_info;
4288         struct kstat stat;
4289
4290         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
4291         file_info = (struct smb2_file_internal_info *)rsp->Buffer;
4292         file_info->IndexNumber = cpu_to_le64(stat.ino);
4293         rsp->OutputBufferLength =
4294                 cpu_to_le32(sizeof(struct smb2_file_internal_info));
4295         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_internal_info));
4296 }
4297
4298 static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
4299                 struct ksmbd_file *fp, void *rsp_org)
4300 {
4301         struct smb2_file_ntwrk_info *file_info;
4302         struct inode *inode;
4303         struct kstat stat;
4304         u64 time;
4305
4306         if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4307                 ksmbd_err("no right to read the attributes : 0x%x\n",
4308                           fp->daccess);
4309                 return -EACCES;
4310         }
4311
4312         file_info = (struct smb2_file_ntwrk_info *)rsp->Buffer;
4313
4314         inode = FP_INODE(fp);
4315         generic_fillattr(&init_user_ns, inode, &stat);
4316
4317         file_info->CreationTime = cpu_to_le64(fp->create_time);
4318         time = ksmbd_UnixTimeToNT(stat.atime);
4319         file_info->LastAccessTime = cpu_to_le64(time);
4320         time = ksmbd_UnixTimeToNT(stat.mtime);
4321         file_info->LastWriteTime = cpu_to_le64(time);
4322         time = ksmbd_UnixTimeToNT(stat.ctime);
4323         file_info->ChangeTime = cpu_to_le64(time);
4324         file_info->Attributes = fp->f_ci->m_fattr;
4325         file_info->AllocationSize =
4326                 cpu_to_le64(get_allocation_size(inode, &stat));
4327         file_info->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
4328         file_info->Reserved = cpu_to_le32(0);
4329         rsp->OutputBufferLength =
4330                 cpu_to_le32(sizeof(struct smb2_file_ntwrk_info));
4331         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_ntwrk_info));
4332         return 0;
4333 }
4334
4335 static void get_file_ea_info(struct smb2_query_info_rsp *rsp, void *rsp_org)
4336 {
4337         struct smb2_file_ea_info *file_info;
4338
4339         file_info = (struct smb2_file_ea_info *)rsp->Buffer;
4340         file_info->EASize = 0;
4341         rsp->OutputBufferLength =
4342                 cpu_to_le32(sizeof(struct smb2_file_ea_info));
4343         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_ea_info));
4344 }
4345
4346 static void get_file_position_info(struct smb2_query_info_rsp *rsp,
4347                 struct ksmbd_file *fp, void *rsp_org)
4348 {
4349         struct smb2_file_pos_info *file_info;
4350
4351         file_info = (struct smb2_file_pos_info *)rsp->Buffer;
4352         file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos);
4353         rsp->OutputBufferLength =
4354                 cpu_to_le32(sizeof(struct smb2_file_pos_info));
4355         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_pos_info));
4356 }
4357
4358 static void get_file_mode_info(struct smb2_query_info_rsp *rsp,
4359                 struct ksmbd_file *fp, void *rsp_org)
4360 {
4361         struct smb2_file_mode_info *file_info;
4362
4363         file_info = (struct smb2_file_mode_info *)rsp->Buffer;
4364         file_info->Mode = fp->coption & FILE_MODE_INFO_MASK;
4365         rsp->OutputBufferLength =
4366                 cpu_to_le32(sizeof(struct smb2_file_mode_info));
4367         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_mode_info));
4368 }
4369
4370 static void get_file_compression_info(struct smb2_query_info_rsp *rsp,
4371                 struct ksmbd_file *fp, void *rsp_org)
4372 {
4373         struct smb2_file_comp_info *file_info;
4374         struct kstat stat;
4375
4376         generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
4377
4378         file_info = (struct smb2_file_comp_info *)rsp->Buffer;
4379         file_info->CompressedFileSize = cpu_to_le64(stat.blocks << 9);
4380         file_info->CompressionFormat = COMPRESSION_FORMAT_NONE;
4381         file_info->CompressionUnitShift = 0;
4382         file_info->ChunkShift = 0;
4383         file_info->ClusterShift = 0;
4384         memset(&file_info->Reserved[0], 0, 3);
4385
4386         rsp->OutputBufferLength =
4387                 cpu_to_le32(sizeof(struct smb2_file_comp_info));
4388         inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_comp_info));
4389 }
4390
4391 static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp,
4392                 struct ksmbd_file *fp, void *rsp_org)
4393 {
4394         struct smb2_file_attr_tag_info *file_info;
4395
4396         if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4397                 ksmbd_err("no right to read the attributes : 0x%x\n",
4398                           fp->daccess);
4399                 return -EACCES;
4400         }
4401
4402         file_info = (struct smb2_file_attr_tag_info *)rsp->Buffer;
4403         file_info->FileAttributes = fp->f_ci->m_fattr;
4404         file_info->ReparseTag = 0;
4405         rsp->OutputBufferLength =
4406                 cpu_to_le32(sizeof(struct smb2_file_attr_tag_info));
4407         inc_rfc1001_len(rsp_org,
4408                 sizeof(struct smb2_file_attr_tag_info));
4409         return 0;
4410 }
4411
4412 static int find_file_posix_info(struct smb2_query_info_rsp *rsp,
4413                 struct ksmbd_file *fp, void *rsp_org)
4414 {
4415         struct smb311_posix_qinfo *file_info;
4416         struct inode *inode = FP_INODE(fp);
4417         u64 time;
4418
4419         file_info = (struct smb311_posix_qinfo *)rsp->Buffer;
4420         file_info->CreationTime = cpu_to_le64(fp->create_time);
4421         time = ksmbd_UnixTimeToNT(inode->i_atime);
4422         file_info->LastAccessTime = cpu_to_le64(time);
4423         time = ksmbd_UnixTimeToNT(inode->i_mtime);
4424         file_info->LastWriteTime = cpu_to_le64(time);
4425         time = ksmbd_UnixTimeToNT(inode->i_ctime);
4426         file_info->ChangeTime = cpu_to_le64(time);
4427         file_info->DosAttributes = fp->f_ci->m_fattr;
4428         file_info->Inode = cpu_to_le64(inode->i_ino);
4429         file_info->EndOfFile = cpu_to_le64(inode->i_size);
4430         file_info->AllocationSize = cpu_to_le64(inode->i_blocks << 9);
4431         file_info->HardLinks = cpu_to_le32(inode->i_nlink);
4432         file_info->Mode = cpu_to_le32(inode->i_mode);
4433         file_info->DeviceId = cpu_to_le32(inode->i_rdev);
4434         rsp->OutputBufferLength =
4435                 cpu_to_le32(sizeof(struct smb311_posix_qinfo));
4436         inc_rfc1001_len(rsp_org, sizeof(struct smb311_posix_qinfo));
4437         return 0;
4438 }
4439
4440 static int smb2_get_info_file(struct ksmbd_work *work,
4441                 struct smb2_query_info_req *req,
4442                 struct smb2_query_info_rsp *rsp, void *rsp_org)
4443 {
4444         struct ksmbd_file *fp;
4445         int fileinfoclass = 0;
4446         int rc = 0;
4447         int file_infoclass_size;
4448         unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
4449
4450         if (test_share_config_flag(work->tcon->share_conf,
4451                                    KSMBD_SHARE_FLAG_PIPE)) {
4452                 /* smb2 info file called for pipe */
4453                 return smb2_get_info_file_pipe(work->sess, req, rsp);
4454         }
4455
4456         if (work->next_smb2_rcv_hdr_off) {
4457                 if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
4458                         ksmbd_debug(SMB, "Compound request set FID = %u\n",
4459                                         work->compound_fid);
4460                         id = work->compound_fid;
4461                         pid = work->compound_pfid;
4462                 }
4463         }
4464
4465         if (!HAS_FILE_ID(id)) {
4466                 id = le64_to_cpu(req->VolatileFileId);
4467                 pid = le64_to_cpu(req->PersistentFileId);
4468         }
4469
4470         fp = ksmbd_lookup_fd_slow(work, id, pid);
4471         if (!fp)
4472                 return -ENOENT;
4473
4474         fileinfoclass = req->FileInfoClass;
4475
4476         switch (fileinfoclass) {
4477         case FILE_ACCESS_INFORMATION:
4478                 get_file_access_info(rsp, fp, rsp_org);
4479                 file_infoclass_size = FILE_ACCESS_INFORMATION_SIZE;
4480                 break;
4481
4482         case FILE_BASIC_INFORMATION:
4483                 rc = get_file_basic_info(rsp, fp, rsp_org);
4484                 file_infoclass_size = FILE_BASIC_INFORMATION_SIZE;
4485                 break;
4486
4487         case FILE_STANDARD_INFORMATION:
4488                 get_file_standard_info(rsp, fp, rsp_org);
4489                 file_infoclass_size = FILE_STANDARD_INFORMATION_SIZE;
4490                 break;
4491
4492         case FILE_ALIGNMENT_INFORMATION:
4493                 get_file_alignment_info(rsp, rsp_org);
4494                 file_infoclass_size = FILE_ALIGNMENT_INFORMATION_SIZE;
4495                 break;
4496
4497         case FILE_ALL_INFORMATION:
4498                 rc = get_file_all_info(work, rsp, fp, rsp_org);
4499                 file_infoclass_size = FILE_ALL_INFORMATION_SIZE;
4500                 break;
4501
4502         case FILE_ALTERNATE_NAME_INFORMATION:
4503                 get_file_alternate_info(work, rsp, fp, rsp_org);
4504                 file_infoclass_size = FILE_ALTERNATE_NAME_INFORMATION_SIZE;
4505                 break;
4506
4507         case FILE_STREAM_INFORMATION:
4508                 get_file_stream_info(work, rsp, fp, rsp_org);
4509                 file_infoclass_size = FILE_STREAM_INFORMATION_SIZE;
4510                 break;
4511
4512         case FILE_INTERNAL_INFORMATION:
4513                 get_file_internal_info(rsp, fp, rsp_org);
4514                 file_infoclass_size = FILE_INTERNAL_INFORMATION_SIZE;
4515                 break;
4516
4517         case FILE_NETWORK_OPEN_INFORMATION:
4518                 rc = get_file_network_open_info(rsp, fp, rsp_org);
4519                 file_infoclass_size = FILE_NETWORK_OPEN_INFORMATION_SIZE;
4520                 break;
4521
4522         case FILE_EA_INFORMATION:
4523                 get_file_ea_info(rsp, rsp_org);
4524                 file_infoclass_size = FILE_EA_INFORMATION_SIZE;
4525                 break;
4526
4527         case FILE_FULL_EA_INFORMATION:
4528                 rc = smb2_get_ea(work, fp, req, rsp, rsp_org);
4529                 file_infoclass_size = FILE_FULL_EA_INFORMATION_SIZE;
4530                 break;
4531
4532         case FILE_POSITION_INFORMATION:
4533                 get_file_position_info(rsp, fp, rsp_org);
4534                 file_infoclass_size = FILE_POSITION_INFORMATION_SIZE;
4535                 break;
4536
4537         case FILE_MODE_INFORMATION:
4538                 get_file_mode_info(rsp, fp, rsp_org);
4539                 file_infoclass_size = FILE_MODE_INFORMATION_SIZE;
4540                 break;
4541
4542         case FILE_COMPRESSION_INFORMATION:
4543                 get_file_compression_info(rsp, fp, rsp_org);
4544                 file_infoclass_size = FILE_COMPRESSION_INFORMATION_SIZE;
4545                 break;
4546
4547         case FILE_ATTRIBUTE_TAG_INFORMATION:
4548                 rc = get_file_attribute_tag_info(rsp, fp, rsp_org);
4549                 file_infoclass_size = FILE_ATTRIBUTE_TAG_INFORMATION_SIZE;
4550                 break;
4551         case SMB_FIND_FILE_POSIX_INFO:
4552                 if (!work->tcon->posix_extensions) {
4553                         ksmbd_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
4554                         rc = -EOPNOTSUPP;
4555                 } else {
4556                         rc = find_file_posix_info(rsp, fp, rsp_org);
4557                         file_infoclass_size = sizeof(struct smb311_posix_qinfo);
4558                 }
4559                 break;
4560         default:
4561                 ksmbd_debug(SMB, "fileinfoclass %d not supported yet\n",
4562                             fileinfoclass);
4563                 rc = -EOPNOTSUPP;
4564         }
4565         if (!rc)
4566                 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
4567                                       rsp,
4568                                       file_infoclass_size);
4569         ksmbd_fd_put(work, fp);
4570         return rc;
4571 }
4572
4573 static int smb2_get_info_filesystem(struct ksmbd_work *work,
4574                 struct smb2_query_info_req *req,
4575                 struct smb2_query_info_rsp *rsp, void *rsp_org)
4576 {
4577         struct ksmbd_session *sess = work->sess;
4578         struct ksmbd_conn *conn = sess->conn;
4579         struct ksmbd_share_config *share = work->tcon->share_conf;
4580         int fsinfoclass = 0;
4581         struct kstatfs stfs;
4582         struct path path;
4583         int rc = 0, len;
4584         int fs_infoclass_size = 0;
4585
4586         rc = ksmbd_vfs_kern_path(share->path, LOOKUP_FOLLOW, &path, 0);
4587         if (rc) {
4588                 ksmbd_err("cannot create vfs path\n");
4589                 return -EIO;
4590         }
4591
4592         rc = vfs_statfs(&path, &stfs);
4593         if (rc) {
4594                 ksmbd_err("cannot do stat of path %s\n", share->path);
4595                 path_put(&path);
4596                 return -EIO;
4597         }
4598
4599         fsinfoclass = req->FileInfoClass;
4600
4601         switch (fsinfoclass) {
4602         case FS_DEVICE_INFORMATION:
4603         {
4604                 struct filesystem_device_info *info;
4605
4606                 info = (struct filesystem_device_info *)rsp->Buffer;
4607
4608                 info->DeviceType = cpu_to_le32(stfs.f_type);
4609                 info->DeviceCharacteristics = cpu_to_le32(0x00000020);
4610                 rsp->OutputBufferLength = cpu_to_le32(8);
4611                 inc_rfc1001_len(rsp_org, 8);
4612                 fs_infoclass_size = FS_DEVICE_INFORMATION_SIZE;
4613                 break;
4614         }
4615         case FS_ATTRIBUTE_INFORMATION:
4616         {
4617                 struct filesystem_attribute_info *info;
4618                 size_t sz;
4619
4620                 info = (struct filesystem_attribute_info *)rsp->Buffer;
4621                 info->Attributes = cpu_to_le32(FILE_SUPPORTS_OBJECT_IDS |
4622                                                FILE_PERSISTENT_ACLS |
4623                                                FILE_UNICODE_ON_DISK |
4624                                                FILE_CASE_PRESERVED_NAMES |
4625                                                FILE_CASE_SENSITIVE_SEARCH |
4626                                                FILE_SUPPORTS_BLOCK_REFCOUNTING);
4627
4628                 info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);
4629
4630                 info->MaxPathNameComponentLength = cpu_to_le32(stfs.f_namelen);
4631                 len = smbConvertToUTF16((__le16 *)info->FileSystemName,
4632                                         "NTFS", PATH_MAX, conn->local_nls, 0);
4633                 len = len * 2;
4634                 info->FileSystemNameLen = cpu_to_le32(len);
4635                 sz = sizeof(struct filesystem_attribute_info) - 2 + len;
4636                 rsp->OutputBufferLength = cpu_to_le32(sz);
4637                 inc_rfc1001_len(rsp_org, sz);
4638                 fs_infoclass_size = FS_ATTRIBUTE_INFORMATION_SIZE;
4639                 break;
4640         }
4641         case FS_VOLUME_INFORMATION:
4642         {
4643                 struct filesystem_vol_info *info;
4644                 size_t sz;
4645
4646                 info = (struct filesystem_vol_info *)(rsp->Buffer);
4647                 info->VolumeCreationTime = 0;
4648                 /* Taking dummy value of serial number*/
4649                 info->SerialNumber = cpu_to_le32(0xbc3ac512);
4650                 len = smbConvertToUTF16((__le16 *)info->VolumeLabel,
4651                                         share->name, PATH_MAX,
4652                                         conn->local_nls, 0);
4653                 len = len * 2;
4654                 info->VolumeLabelSize = cpu_to_le32(len);
4655                 info->Reserved = 0;
4656                 sz = sizeof(struct filesystem_vol_info) - 2 + len;
4657                 rsp->OutputBufferLength = cpu_to_le32(sz);
4658                 inc_rfc1001_len(rsp_org, sz);
4659                 fs_infoclass_size = FS_VOLUME_INFORMATION_SIZE;
4660                 break;
4661         }
4662         case FS_SIZE_INFORMATION:
4663         {
4664                 struct filesystem_info *info;
4665                 unsigned short logical_sector_size;
4666
4667                 info = (struct filesystem_info *)(rsp->Buffer);
4668                 logical_sector_size =
4669                         ksmbd_vfs_logical_sector_size(d_inode(path.dentry));
4670
4671                 info->TotalAllocationUnits = cpu_to_le64(stfs.f_blocks);
4672                 info->FreeAllocationUnits = cpu_to_le64(stfs.f_bfree);
4673                 info->SectorsPerAllocationUnit = cpu_to_le32(stfs.f_bsize >> 9);
4674                 info->BytesPerSector = cpu_to_le32(logical_sector_size);
4675                 rsp->OutputBufferLength = cpu_to_le32(24);
4676                 inc_rfc1001_len(rsp_org, 24);
4677                 fs_infoclass_size = FS_SIZE_INFORMATION_SIZE;
4678                 break;
4679         }
4680         case FS_FULL_SIZE_INFORMATION:
4681         {
4682                 struct smb2_fs_full_size_info *info;
4683                 unsigned short logical_sector_size;
4684
4685                 info = (struct smb2_fs_full_size_info *)(rsp->Buffer);
4686                 logical_sector_size =
4687                         ksmbd_vfs_logical_sector_size(d_inode(path.dentry));
4688
4689                 info->TotalAllocationUnits = cpu_to_le64(stfs.f_blocks);
4690                 info->CallerAvailableAllocationUnits =
4691                                         cpu_to_le64(stfs.f_bavail);
4692                 info->ActualAvailableAllocationUnits =
4693                                         cpu_to_le64(stfs.f_bfree);
4694                 info->SectorsPerAllocationUnit = cpu_to_le32(stfs.f_bsize >> 9);
4695                 info->BytesPerSector = cpu_to_le32(logical_sector_size);
4696                 rsp->OutputBufferLength = cpu_to_le32(32);
4697                 inc_rfc1001_len(rsp_org, 32);
4698                 fs_infoclass_size = FS_FULL_SIZE_INFORMATION_SIZE;
4699                 break;
4700         }
4701         case FS_OBJECT_ID_INFORMATION:
4702         {
4703                 struct object_id_info *info;
4704
4705                 info = (struct object_id_info *)(rsp->Buffer);
4706
4707                 if (!user_guest(sess->user))
4708                         memcpy(info->objid, user_passkey(sess->user), 16);
4709                 else
4710                         memset(info->objid, 0, 16);
4711
4712                 info->extended_info.magic = cpu_to_le32(EXTENDED_INFO_MAGIC);
4713                 info->extended_info.version = cpu_to_le32(1);
4714                 info->extended_info.release = cpu_to_le32(1);
4715                 info->extended_info.rel_date = 0;
4716                 memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0"));
4717                 rsp->OutputBufferLength = cpu_to_le32(64);
4718                 inc_rfc1001_len(rsp_org, 64);
4719                 fs_infoclass_size = FS_OBJECT_ID_INFORMATION_SIZE;
4720                 break;
4721         }
4722         case FS_SECTOR_SIZE_INFORMATION:
4723         {
4724                 struct smb3_fs_ss_info *info;
4725                 struct ksmbd_fs_sector_size fs_ss;
4726
4727                 info = (struct smb3_fs_ss_info *)(rsp->Buffer);
4728                 ksmbd_vfs_smb2_sector_size(d_inode(path.dentry), &fs_ss);
4729
4730                 info->LogicalBytesPerSector =
4731                                 cpu_to_le32(fs_ss.logical_sector_size);
4732                 info->PhysicalBytesPerSectorForAtomicity =
4733                                 cpu_to_le32(fs_ss.physical_sector_size);
4734                 info->PhysicalBytesPerSectorForPerf =
4735                                 cpu_to_le32(fs_ss.optimal_io_size);
4736                 info->FSEffPhysicalBytesPerSectorForAtomicity =
4737                                 cpu_to_le32(fs_ss.optimal_io_size);
4738                 info->Flags = cpu_to_le32(SSINFO_FLAGS_ALIGNED_DEVICE |
4739                                     SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);
4740                 info->ByteOffsetForSectorAlignment = 0;
4741                 info->ByteOffsetForPartitionAlignment = 0;
4742                 rsp->OutputBufferLength = cpu_to_le32(28);
4743                 inc_rfc1001_len(rsp_org, 28);
4744                 fs_infoclass_size = FS_SECTOR_SIZE_INFORMATION_SIZE;
4745                 break;
4746         }
4747         case FS_CONTROL_INFORMATION:
4748         {
4749                 /*
4750                  * TODO : The current implementation is based on
4751                  * test result with win7(NTFS) server. It's need to
4752                  * modify this to get valid Quota values
4753                  * from Linux kernel
4754                  */
4755                 struct smb2_fs_control_info *info;
4756
4757                 info = (struct smb2_fs_control_info *)(rsp->Buffer);
4758                 info->FreeSpaceStartFiltering = 0;
4759                 info->FreeSpaceThreshold = 0;
4760                 info->FreeSpaceStopFiltering = 0;
4761                 info->DefaultQuotaThreshold = cpu_to_le64(SMB2_NO_FID);
4762                 info->DefaultQuotaLimit = cpu_to_le64(SMB2_NO_FID);
4763                 info->Padding = 0;
4764                 rsp->OutputBufferLength = cpu_to_le32(48);
4765                 inc_rfc1001_len(rsp_org, 48);
4766                 fs_infoclass_size = FS_CONTROL_INFORMATION_SIZE;
4767                 break;
4768         }
4769         case FS_POSIX_INFORMATION:
4770         {
4771                 struct filesystem_posix_info *info;
4772                 unsigned short logical_sector_size;
4773
4774                 if (!work->tcon->posix_extensions) {
4775                         ksmbd_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
4776                         rc = -EOPNOTSUPP;
4777                 } else {
4778                         info = (struct filesystem_posix_info *)(rsp->Buffer);
4779                         logical_sector_size =
4780                                 ksmbd_vfs_logical_sector_size(d_inode(path.dentry));
4781                         info->OptimalTransferSize = cpu_to_le32(logical_sector_size);
4782                         info->BlockSize = cpu_to_le32(stfs.f_bsize);
4783                         info->TotalBlocks = cpu_to_le64(stfs.f_blocks);
4784                         info->BlocksAvail = cpu_to_le64(stfs.f_bfree);
4785                         info->UserBlocksAvail = cpu_to_le64(stfs.f_bavail);
4786                         info->TotalFileNodes = cpu_to_le64(stfs.f_files);
4787                         info->FreeFileNodes = cpu_to_le64(stfs.f_ffree);
4788                         rsp->OutputBufferLength = cpu_to_le32(56);
4789                         inc_rfc1001_len(rsp_org, 56);
4790                         fs_infoclass_size = FS_POSIX_INFORMATION_SIZE;
4791                 }
4792                 break;
4793         }
4794         default:
4795                 path_put(&path);
4796                 return -EOPNOTSUPP;
4797         }
4798         rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
4799                               rsp,
4800                               fs_infoclass_size);
4801         path_put(&path);
4802         return rc;
4803 }
4804
4805 static int smb2_get_info_sec(struct ksmbd_work *work,
4806                 struct smb2_query_info_req *req,
4807                 struct smb2_query_info_rsp *rsp, void *rsp_org)
4808 {
4809         struct ksmbd_file *fp;
4810         struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL;
4811         struct smb_fattr fattr = {{0}};
4812         struct inode *inode;
4813         __u32 secdesclen;
4814         unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
4815         int addition_info = le32_to_cpu(req->AdditionalInformation);
4816         int rc;
4817
4818         if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO)) {
4819                 ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n",
4820                         addition_info);
4821
4822                 pntsd->revision = cpu_to_le16(1);
4823                 pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PROTECTED);
4824                 pntsd->osidoffset = 0;
4825                 pntsd->gsidoffset = 0;
4826                 pntsd->sacloffset = 0;
4827                 pntsd->dacloffset = 0;
4828
4829                 secdesclen = sizeof(struct smb_ntsd);
4830                 rsp->OutputBufferLength = cpu_to_le32(secdesclen);
4831                 inc_rfc1001_len(rsp_org, secdesclen);
4832
4833                 return 0;
4834         }
4835
4836         if (work->next_smb2_rcv_hdr_off) {
4837                 if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
4838                         ksmbd_debug(SMB, "Compound request set FID = %u\n",
4839                                         work->compound_fid);
4840                         id = work->compound_fid;
4841                         pid = work->compound_pfid;
4842                 }
4843         }
4844
4845         if (!HAS_FILE_ID(id)) {
4846                 id = le64_to_cpu(req->VolatileFileId);
4847                 pid = le64_to_cpu(req->PersistentFileId);
4848         }
4849
4850         fp = ksmbd_lookup_fd_slow(work, id, pid);
4851         if (!fp)
4852                 return -ENOENT;
4853
4854         inode = FP_INODE(fp);
4855         ksmbd_acls_fattr(&fattr, inode);
4856
4857         if (test_share_config_flag(work->tcon->share_conf,
4858                                    KSMBD_SHARE_FLAG_ACL_XATTR))
4859                 ksmbd_vfs_get_sd_xattr(work->conn, fp->filp->f_path.dentry, &ppntsd);
4860
4861         rc = build_sec_desc(pntsd, ppntsd, addition_info, &secdesclen, &fattr);
4862         posix_acl_release(fattr.cf_acls);
4863         posix_acl_release(fattr.cf_dacls);
4864         kfree(ppntsd);
4865         ksmbd_fd_put(work, fp);
4866         if (rc)
4867                 return rc;
4868
4869         rsp->OutputBufferLength = cpu_to_le32(secdesclen);
4870         inc_rfc1001_len(rsp_org, secdesclen);
4871         return 0;
4872 }
4873
4874 /**
4875  * smb2_query_info() - handler for smb2 query info command
4876  * @work:       smb work containing query info request buffer
4877  *
4878  * Return:      0 on success, otherwise error
4879  */
4880 int smb2_query_info(struct ksmbd_work *work)
4881 {
4882         struct smb2_query_info_req *req;
4883         struct smb2_query_info_rsp *rsp, *rsp_org;
4884         int rc = 0;
4885
4886         rsp_org = work->response_buf;
4887         WORK_BUFFERS(work, req, rsp);
4888
4889         ksmbd_debug(SMB, "GOT query info request\n");
4890
4891         switch (req->InfoType) {
4892         case SMB2_O_INFO_FILE:
4893                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n");
4894                 rc = smb2_get_info_file(work, req, rsp, (void *)rsp_org);
4895                 break;
4896         case SMB2_O_INFO_FILESYSTEM:
4897                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILESYSTEM\n");
4898                 rc = smb2_get_info_filesystem(work, req, rsp, (void *)rsp_org);
4899                 break;
4900         case SMB2_O_INFO_SECURITY:
4901                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
4902                 rc = smb2_get_info_sec(work, req, rsp, (void *)rsp_org);
4903                 break;
4904         default:
4905                 ksmbd_debug(SMB, "InfoType %d not supported yet\n",
4906                         req->InfoType);
4907                 rc = -EOPNOTSUPP;
4908         }
4909
4910         if (rc < 0) {
4911                 if (rc == -EACCES)
4912                         rsp->hdr.Status = STATUS_ACCESS_DENIED;
4913                 else if (rc == -ENOENT)
4914                         rsp->hdr.Status = STATUS_FILE_CLOSED;
4915                 else if (rc == -EIO)
4916                         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
4917                 else if (rc == -EOPNOTSUPP || rsp->hdr.Status == 0)
4918                         rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
4919                 smb2_set_err_rsp(work);
4920
4921                 ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n",
4922                               rc);
4923                 return rc;
4924         }
4925         rsp->StructureSize = cpu_to_le16(9);
4926         rsp->OutputBufferOffset = cpu_to_le16(72);
4927         inc_rfc1001_len(rsp_org, 8);
4928         return 0;
4929 }
4930
4931 /**
4932  * smb2_close_pipe() - handler for closing IPC pipe
4933  * @work:       smb work containing close request buffer
4934  *
4935  * Return:      0
4936  */
4937 static noinline int smb2_close_pipe(struct ksmbd_work *work)
4938 {
4939         u64 id;
4940         struct smb2_close_req *req = work->request_buf;
4941         struct smb2_close_rsp *rsp = work->response_buf;
4942
4943         id = le64_to_cpu(req->VolatileFileId);
4944         ksmbd_session_rpc_close(work->sess, id);
4945
4946         rsp->StructureSize = cpu_to_le16(60);
4947         rsp->Flags = 0;
4948         rsp->Reserved = 0;
4949         rsp->CreationTime = 0;
4950         rsp->LastAccessTime = 0;
4951         rsp->LastWriteTime = 0;
4952         rsp->ChangeTime = 0;
4953         rsp->AllocationSize = 0;
4954         rsp->EndOfFile = 0;
4955         rsp->Attributes = 0;
4956         inc_rfc1001_len(rsp, 60);
4957         return 0;
4958 }
4959
4960 /**
4961  * smb2_close() - handler for smb2 close file command
4962  * @work:       smb work containing close request buffer
4963  *
4964  * Return:      0
4965  */
4966 int smb2_close(struct ksmbd_work *work)
4967 {
4968         unsigned int volatile_id = KSMBD_NO_FID;
4969         u64 sess_id;
4970         struct smb2_close_req *req;
4971         struct smb2_close_rsp *rsp;
4972         struct smb2_close_rsp *rsp_org;
4973         struct ksmbd_conn *conn = work->conn;
4974         struct ksmbd_file *fp;
4975         struct inode *inode;
4976         u64 time;
4977         int err = 0;
4978
4979         rsp_org = work->response_buf;
4980         WORK_BUFFERS(work, req, rsp);
4981
4982         if (test_share_config_flag(work->tcon->share_conf,
4983                                    KSMBD_SHARE_FLAG_PIPE)) {
4984                 ksmbd_debug(SMB, "IPC pipe close request\n");
4985                 return smb2_close_pipe(work);
4986         }
4987
4988         sess_id = le64_to_cpu(req->hdr.SessionId);
4989         if (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)
4990                 sess_id = work->compound_sid;
4991
4992         work->compound_sid = 0;
4993         if (check_session_id(conn, sess_id)) {
4994                 work->compound_sid = sess_id;
4995         } else {
4996                 rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
4997                 if (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)
4998                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
4999                 err = -EBADF;
5000                 goto out;
5001         }
5002
5003         if (work->next_smb2_rcv_hdr_off &&
5004             !HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
5005                 if (!HAS_FILE_ID(work->compound_fid)) {
5006                         /* file already closed, return FILE_CLOSED */
5007                         ksmbd_debug(SMB, "file already closed\n");
5008                         rsp->hdr.Status = STATUS_FILE_CLOSED;
5009                         err = -EBADF;
5010                         goto out;
5011                 } else {
5012                         ksmbd_debug(SMB, "Compound request set FID = %u:%u\n",
5013                                         work->compound_fid,
5014                                         work->compound_pfid);
5015                         volatile_id = work->compound_fid;
5016
5017                         /* file closed, stored id is not valid anymore */
5018                         work->compound_fid = KSMBD_NO_FID;
5019                         work->compound_pfid = KSMBD_NO_FID;
5020                 }
5021         } else {
5022                 volatile_id = le64_to_cpu(req->VolatileFileId);
5023         }
5024         ksmbd_debug(SMB, "volatile_id = %u\n", volatile_id);
5025
5026         rsp->StructureSize = cpu_to_le16(60);
5027         rsp->Reserved = 0;
5028
5029         if (req->Flags == SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB) {
5030                 fp = ksmbd_lookup_fd_fast(work, volatile_id);
5031                 if (!fp) {
5032                         err = -ENOENT;
5033                         goto out;
5034                 }
5035
5036                 inode = FP_INODE(fp);
5037                 rsp->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
5038                 rsp->AllocationSize = S_ISDIR(inode->i_mode) ? 0 :
5039                         cpu_to_le64(inode->i_blocks << 9);
5040                 rsp->EndOfFile = cpu_to_le64(inode->i_size);
5041                 rsp->Attributes = fp->f_ci->m_fattr;
5042                 rsp->CreationTime = cpu_to_le64(fp->create_time);
5043                 time = ksmbd_UnixTimeToNT(inode->i_atime);
5044                 rsp->LastAccessTime = cpu_to_le64(time);
5045                 time = ksmbd_UnixTimeToNT(inode->i_mtime);
5046                 rsp->LastWriteTime = cpu_to_le64(time);
5047                 time = ksmbd_UnixTimeToNT(inode->i_ctime);
5048                 rsp->ChangeTime = cpu_to_le64(time);
5049                 ksmbd_fd_put(work, fp);
5050         } else {
5051                 rsp->Flags = 0;
5052                 rsp->AllocationSize = 0;
5053                 rsp->EndOfFile = 0;
5054                 rsp->Attributes = 0;
5055                 rsp->CreationTime = 0;
5056                 rsp->LastAccessTime = 0;
5057                 rsp->LastWriteTime = 0;
5058                 rsp->ChangeTime = 0;
5059         }
5060
5061         err = ksmbd_close_fd(work, volatile_id);
5062 out:
5063         if (err) {
5064                 if (rsp->hdr.Status == 0)
5065                         rsp->hdr.Status = STATUS_FILE_CLOSED;
5066                 smb2_set_err_rsp(work);
5067         } else {
5068                 inc_rfc1001_len(rsp_org, 60);
5069         }
5070
5071         return 0;
5072 }
5073
5074 /**
5075  * smb2_echo() - handler for smb2 echo(ping) command
5076  * @work:       smb work containing echo request buffer
5077  *
5078  * Return:      0
5079  */
5080 int smb2_echo(struct ksmbd_work *work)
5081 {
5082         struct smb2_echo_rsp *rsp = work->response_buf;
5083
5084         rsp->StructureSize = cpu_to_le16(4);
5085         rsp->Reserved = 0;
5086         inc_rfc1001_len(rsp, 4);
5087         return 0;
5088 }
5089
5090 static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
5091                 struct smb2_file_rename_info *file_info,
5092                 struct nls_table *local_nls)
5093 {
5094         struct ksmbd_share_config *share = fp->tcon->share_conf;
5095         char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL;
5096         char *pathname = NULL;
5097         struct path path;
5098         bool file_present = true;
5099         int rc;
5100
5101         ksmbd_debug(SMB, "setting FILE_RENAME_INFO\n");
5102         pathname = kmalloc(PATH_MAX, GFP_KERNEL);
5103         if (!pathname)
5104                 return -ENOMEM;
5105
5106         abs_oldname = d_path(&fp->filp->f_path, pathname, PATH_MAX);
5107         if (IS_ERR(abs_oldname)) {
5108                 rc = -EINVAL;
5109                 goto out;
5110         }
5111         old_name = strrchr(abs_oldname, '/');
5112         if (old_name && old_name[1] != '\0') {
5113                 old_name++;
5114         } else {
5115                 ksmbd_debug(SMB, "can't get last component in path %s\n",
5116                                 abs_oldname);
5117                 rc = -ENOENT;
5118                 goto out;
5119         }
5120
5121         new_name = smb2_get_name(share,
5122                                  file_info->FileName,
5123                                  le32_to_cpu(file_info->FileNameLength),
5124                                  local_nls);
5125         if (IS_ERR(new_name)) {
5126                 rc = PTR_ERR(new_name);
5127                 goto out;
5128         }
5129
5130         if (strchr(new_name, ':')) {
5131                 int s_type;
5132                 char *xattr_stream_name, *stream_name = NULL;
5133                 size_t xattr_stream_size;
5134                 int len;
5135
5136                 rc = parse_stream_name(new_name, &stream_name, &s_type);
5137                 if (rc < 0)
5138                         goto out;
5139
5140                 len = strlen(new_name);
5141                 if (new_name[len - 1] != '/') {
5142                         ksmbd_err("not allow base filename in rename\n");
5143                         rc = -ESHARE;
5144                         goto out;
5145                 }
5146
5147                 rc = ksmbd_vfs_xattr_stream_name(stream_name,
5148                                                  &xattr_stream_name,
5149                                                  &xattr_stream_size,
5150                                                  s_type);
5151                 if (rc)
5152                         goto out;
5153
5154                 rc = ksmbd_vfs_setxattr(fp->filp->f_path.dentry,
5155                                         xattr_stream_name,
5156                                         NULL, 0, 0);
5157                 if (rc < 0) {
5158                         ksmbd_err("failed to store stream name in xattr: %d\n",
5159                                    rc);
5160                         rc = -EINVAL;
5161                         goto out;
5162                 }
5163
5164                 goto out;
5165         }
5166
5167         ksmbd_debug(SMB, "new name %s\n", new_name);
5168         rc = ksmbd_vfs_kern_path(new_name, 0, &path, 1);
5169         if (rc)
5170                 file_present = false;
5171         else
5172                 path_put(&path);
5173
5174         if (ksmbd_share_veto_filename(share, new_name)) {
5175                 rc = -ENOENT;
5176                 ksmbd_debug(SMB, "Can't rename vetoed file: %s\n", new_name);
5177                 goto out;
5178         }
5179
5180         if (file_info->ReplaceIfExists) {
5181                 if (file_present) {
5182                         rc = ksmbd_vfs_remove_file(work, new_name);
5183                         if (rc) {
5184                                 if (rc != -ENOTEMPTY)
5185                                         rc = -EINVAL;
5186                                 ksmbd_debug(SMB, "cannot delete %s, rc %d\n",
5187                                                 new_name, rc);
5188                                 goto out;
5189                         }
5190                 }
5191         } else {
5192                 if (file_present &&
5193                     strncmp(old_name, path.dentry->d_name.name, strlen(old_name))) {
5194                         rc = -EEXIST;
5195                         ksmbd_debug(SMB,
5196                                 "cannot rename already existing file\n");
5197                         goto out;
5198                 }
5199         }
5200
5201         rc = ksmbd_vfs_fp_rename(work, fp, new_name);
5202 out:
5203         kfree(pathname);
5204         if (!IS_ERR(new_name))
5205                 kfree(new_name);
5206         return rc;
5207 }
5208
5209 static int smb2_create_link(struct ksmbd_work *work,
5210                 struct ksmbd_share_config *share,
5211                 struct smb2_file_link_info *file_info, struct file *filp,
5212                 struct nls_table *local_nls)
5213 {
5214         char *link_name = NULL, *target_name = NULL, *pathname = NULL;
5215         struct path path;
5216         bool file_present = true;
5217         int rc;
5218
5219         ksmbd_debug(SMB, "setting FILE_LINK_INFORMATION\n");
5220         pathname = kmalloc(PATH_MAX, GFP_KERNEL);
5221         if (!pathname)
5222                 return -ENOMEM;
5223
5224         link_name = smb2_get_name(share,
5225                                   file_info->FileName,
5226                                   le32_to_cpu(file_info->FileNameLength),
5227                                   local_nls);
5228         if (IS_ERR(link_name) || S_ISDIR(file_inode(filp)->i_mode)) {
5229                 rc = -EINVAL;
5230                 goto out;
5231         }
5232
5233         ksmbd_debug(SMB, "link name is %s\n", link_name);
5234         target_name = d_path(&filp->f_path, pathname, PATH_MAX);
5235         if (IS_ERR(target_name)) {
5236                 rc = -EINVAL;
5237                 goto out;
5238         }
5239
5240         ksmbd_debug(SMB, "target name is %s\n", target_name);
5241         rc = ksmbd_vfs_kern_path(link_name, 0, &path, 0);
5242         if (rc)
5243                 file_present = false;
5244         else
5245                 path_put(&path);
5246
5247         if (file_info->ReplaceIfExists) {
5248                 if (file_present) {
5249                         rc = ksmbd_vfs_remove_file(work, link_name);
5250                         if (rc) {
5251                                 rc = -EINVAL;
5252                                 ksmbd_debug(SMB, "cannot delete %s\n",
5253                                         link_name);
5254                                 goto out;
5255                         }
5256                 }
5257         } else {
5258                 if (file_present) {
5259                         rc = -EEXIST;
5260                         ksmbd_debug(SMB, "link already exists\n");
5261                         goto out;
5262                 }
5263         }
5264
5265         rc = ksmbd_vfs_link(work, target_name, link_name);
5266         if (rc)
5267                 rc = -EINVAL;
5268 out:
5269         if (!IS_ERR(link_name))
5270                 kfree(link_name);
5271         kfree(pathname);
5272         return rc;
5273 }
5274
5275 static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
5276                 struct ksmbd_share_config *share)
5277 {
5278         struct smb2_file_all_info *file_info;
5279         struct iattr attrs;
5280         struct iattr temp_attrs;
5281         struct file *filp;
5282         struct inode *inode;
5283         int rc;
5284
5285         if (!(fp->daccess & FILE_WRITE_ATTRIBUTES_LE))
5286                 return -EACCES;
5287
5288         file_info = (struct smb2_file_all_info *)buf;
5289         attrs.ia_valid = 0;
5290         filp = fp->filp;
5291         inode = file_inode(filp);
5292
5293         if (file_info->CreationTime)
5294                 fp->create_time = le64_to_cpu(file_info->CreationTime);
5295
5296         if (file_info->LastAccessTime) {
5297                 attrs.ia_atime = ksmbd_NTtimeToUnix(file_info->LastAccessTime);
5298                 attrs.ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
5299         }
5300
5301         if (file_info->ChangeTime) {
5302                 temp_attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime);
5303                 attrs.ia_ctime = temp_attrs.ia_ctime;
5304                 attrs.ia_valid |= ATTR_CTIME;
5305         } else {
5306                 temp_attrs.ia_ctime = inode->i_ctime;
5307         }
5308
5309         if (file_info->LastWriteTime) {
5310                 attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime);
5311                 attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
5312         }
5313
5314         if (file_info->Attributes) {
5315                 if (!S_ISDIR(inode->i_mode) &&
5316                     file_info->Attributes & ATTR_DIRECTORY_LE) {
5317                         ksmbd_err("can't change a file to a directory\n");
5318                         return -EINVAL;
5319                 }
5320
5321                 if (!(S_ISDIR(inode->i_mode) && file_info->Attributes == ATTR_NORMAL_LE))
5322                         fp->f_ci->m_fattr = file_info->Attributes |
5323                                 (fp->f_ci->m_fattr & ATTR_DIRECTORY_LE);
5324         }
5325
5326         if (test_share_config_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS) &&
5327             (file_info->CreationTime || file_info->Attributes)) {
5328                 struct xattr_dos_attrib da = {0};
5329
5330                 da.version = 4;
5331                 da.itime = fp->itime;
5332                 da.create_time = fp->create_time;
5333                 da.attr = le32_to_cpu(fp->f_ci->m_fattr);
5334                 da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
5335                         XATTR_DOSINFO_ITIME;
5336
5337                 rc = ksmbd_vfs_set_dos_attrib_xattr(filp->f_path.dentry, &da);
5338                 if (rc)
5339                         ksmbd_debug(SMB,
5340                                 "failed to restore file attribute in EA\n");
5341                 rc = 0;
5342         }
5343
5344         /*
5345          * HACK : set ctime here to avoid ctime changed
5346          * when file_info->ChangeTime is zero.
5347          */
5348         attrs.ia_ctime = temp_attrs.ia_ctime;
5349         attrs.ia_valid |= ATTR_CTIME;
5350
5351         if (attrs.ia_valid) {
5352                 struct dentry *dentry = filp->f_path.dentry;
5353                 struct inode *inode = d_inode(dentry);
5354
5355                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
5356                         return -EACCES;
5357
5358                 rc = setattr_prepare(&init_user_ns, dentry, &attrs);
5359                 if (rc)
5360                         return -EINVAL;
5361
5362                 inode_lock(inode);
5363                 setattr_copy(&init_user_ns, inode, &attrs);
5364                 attrs.ia_valid &= ~ATTR_CTIME;
5365                 rc = notify_change(&init_user_ns, dentry, &attrs, NULL);
5366                 inode_unlock(inode);
5367         }
5368         return 0;
5369 }
5370
5371 static int set_file_allocation_info(struct ksmbd_work *work,
5372                 struct ksmbd_file *fp, char *buf)
5373 {
5374         /*
5375          * TODO : It's working fine only when store dos attributes
5376          * is not yes. need to implement a logic which works
5377          * properly with any smb.conf option
5378          */
5379
5380         struct smb2_file_alloc_info *file_alloc_info;
5381         loff_t alloc_blks;
5382         struct inode *inode;
5383         int rc;
5384
5385         if (!(fp->daccess & FILE_WRITE_DATA_LE))
5386                 return -EACCES;
5387
5388         file_alloc_info = (struct smb2_file_alloc_info *)buf;
5389         alloc_blks = (le64_to_cpu(file_alloc_info->AllocationSize) + 511) >> 9;
5390         inode = file_inode(fp->filp);
5391
5392         if (alloc_blks > inode->i_blocks) {
5393                 rc = ksmbd_vfs_alloc_size(work, fp, alloc_blks * 512);
5394                 if (rc && rc != -EOPNOTSUPP) {
5395                         ksmbd_err("ksmbd_vfs_alloc_size is failed : %d\n", rc);
5396                         return rc;
5397                 }
5398         } else if (alloc_blks < inode->i_blocks) {
5399                 loff_t size;
5400
5401                 /*
5402                  * Allocation size could be smaller than original one
5403                  * which means allocated blocks in file should be
5404                  * deallocated. use truncate to cut out it, but inode
5405                  * size is also updated with truncate offset.
5406                  * inode size is retained by backup inode size.
5407                  */
5408                 size = i_size_read(inode);
5409                 rc = ksmbd_vfs_truncate(work, NULL, fp, alloc_blks * 512);
5410                 if (rc) {
5411                         ksmbd_err("truncate failed! filename : %s, err %d\n",
5412                                   fp->filename, rc);
5413                         return rc;
5414                 }
5415                 if (size < alloc_blks * 512)
5416                         i_size_write(inode, size);
5417         }
5418         return 0;
5419 }
5420
5421 static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
5422                 char *buf)
5423 {
5424         struct smb2_file_eof_info *file_eof_info;
5425         loff_t newsize;
5426         struct inode *inode;
5427         int rc;
5428
5429         if (!(fp->daccess & FILE_WRITE_DATA_LE))
5430                 return -EACCES;
5431
5432         file_eof_info = (struct smb2_file_eof_info *)buf;
5433         newsize = le64_to_cpu(file_eof_info->EndOfFile);
5434         inode = file_inode(fp->filp);
5435
5436         /*
5437          * If FILE_END_OF_FILE_INFORMATION of set_info_file is called
5438          * on FAT32 shared device, truncate execution time is too long
5439          * and network error could cause from windows client. because
5440          * truncate of some filesystem like FAT32 fill zero data in
5441          * truncated range.
5442          */
5443         if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) {
5444                 ksmbd_debug(SMB, "filename : %s truncated to newsize %lld\n",
5445                                 fp->filename, newsize);
5446                 rc = ksmbd_vfs_truncate(work, NULL, fp, newsize);
5447                 if (rc) {
5448                         ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n",
5449                                         fp->filename, rc);
5450                         if (rc != -EAGAIN)
5451                                 rc = -EBADF;
5452                         return rc;
5453                 }
5454         }
5455         return 0;
5456 }
5457
5458 static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
5459                 char *buf)
5460 {
5461         struct ksmbd_file *parent_fp;
5462
5463         if (!(fp->daccess & FILE_DELETE_LE)) {
5464                 ksmbd_err("no right to delete : 0x%x\n", fp->daccess);
5465                 return -EACCES;
5466         }
5467
5468         if (ksmbd_stream_fd(fp))
5469                 goto next;
5470
5471         parent_fp = ksmbd_lookup_fd_inode(PARENT_INODE(fp));
5472         if (parent_fp) {
5473                 if (parent_fp->daccess & FILE_DELETE_LE) {
5474                         ksmbd_err("parent dir is opened with delete access\n");
5475                         return -ESHARE;
5476                 }
5477         }
5478 next:
5479         return smb2_rename(work, fp,
5480                            (struct smb2_file_rename_info *)buf,
5481                            work->sess->conn->local_nls);
5482 }
5483
5484 static int set_file_disposition_info(struct ksmbd_file *fp, char *buf)
5485 {
5486         struct smb2_file_disposition_info *file_info;
5487         struct inode *inode;
5488
5489         if (!(fp->daccess & FILE_DELETE_LE)) {
5490                 ksmbd_err("no right to delete : 0x%x\n", fp->daccess);
5491                 return -EACCES;
5492         }
5493
5494         inode = file_inode(fp->filp);
5495         file_info = (struct smb2_file_disposition_info *)buf;
5496         if (file_info->DeletePending) {
5497                 if (S_ISDIR(inode->i_mode) &&
5498                     ksmbd_vfs_empty_dir(fp) == -ENOTEMPTY)
5499                         return -EBUSY;
5500                 ksmbd_set_inode_pending_delete(fp);
5501         } else {
5502                 ksmbd_clear_inode_pending_delete(fp);
5503         }
5504         return 0;
5505 }
5506
5507 static int set_file_position_info(struct ksmbd_file *fp, char *buf)
5508 {
5509         struct smb2_file_pos_info *file_info;
5510         loff_t current_byte_offset;
5511         unsigned short sector_size;
5512         struct inode *inode;
5513
5514         inode = file_inode(fp->filp);
5515         file_info = (struct smb2_file_pos_info *)buf;
5516         current_byte_offset = le64_to_cpu(file_info->CurrentByteOffset);
5517         sector_size = ksmbd_vfs_logical_sector_size(inode);
5518
5519         if (current_byte_offset < 0 ||
5520             (fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE &&
5521              current_byte_offset & (sector_size - 1))) {
5522                 ksmbd_err("CurrentByteOffset is not valid : %llu\n",
5523                         current_byte_offset);
5524                 return -EINVAL;
5525         }
5526
5527         fp->filp->f_pos = current_byte_offset;
5528         return 0;
5529 }
5530
5531 static int set_file_mode_info(struct ksmbd_file *fp, char *buf)
5532 {
5533         struct smb2_file_mode_info *file_info;
5534         __le32 mode;
5535
5536         file_info = (struct smb2_file_mode_info *)buf;
5537         mode = file_info->Mode;
5538
5539         if ((mode & ~FILE_MODE_INFO_MASK) ||
5540             (mode & FILE_SYNCHRONOUS_IO_ALERT_LE &&
5541              mode & FILE_SYNCHRONOUS_IO_NONALERT_LE)) {
5542                 ksmbd_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode));
5543                 return -EINVAL;
5544         }
5545
5546         /*
5547          * TODO : need to implement consideration for
5548          * FILE_SYNCHRONOUS_IO_ALERT and FILE_SYNCHRONOUS_IO_NONALERT
5549          */
5550         ksmbd_vfs_set_fadvise(fp->filp, mode);
5551         fp->coption = mode;
5552         return 0;
5553 }
5554
5555 /**
5556  * smb2_set_info_file() - handler for smb2 set info command
5557  * @work:       smb work containing set info command buffer
5558  * @fp:         ksmbd_file pointer
5559  * @info_class: smb2 set info class
5560  * @share:      ksmbd_share_config pointer
5561  *
5562  * Return:      0 on success, otherwise error
5563  * TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH
5564  */
5565 static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
5566                 int info_class, char *buf, struct ksmbd_share_config *share)
5567 {
5568         switch (info_class) {
5569         case FILE_BASIC_INFORMATION:
5570                 return set_file_basic_info(fp, buf, share);
5571
5572         case FILE_ALLOCATION_INFORMATION:
5573                 return set_file_allocation_info(work, fp, buf);
5574
5575         case FILE_END_OF_FILE_INFORMATION:
5576                 return set_end_of_file_info(work, fp, buf);
5577
5578         case FILE_RENAME_INFORMATION:
5579                 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
5580                         ksmbd_debug(SMB,
5581                                 "User does not have write permission\n");
5582                         return -EACCES;
5583                 }
5584                 return set_rename_info(work, fp, buf);
5585
5586         case FILE_LINK_INFORMATION:
5587                 return smb2_create_link(work, work->tcon->share_conf,
5588                         (struct smb2_file_link_info *)buf, fp->filp,
5589                                 work->sess->conn->local_nls);
5590
5591         case FILE_DISPOSITION_INFORMATION:
5592                 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
5593                         ksmbd_debug(SMB,
5594                                 "User does not have write permission\n");
5595                         return -EACCES;
5596                 }
5597                 return set_file_disposition_info(fp, buf);
5598
5599         case FILE_FULL_EA_INFORMATION:
5600         {
5601                 if (!(fp->daccess & FILE_WRITE_EA_LE)) {
5602                         ksmbd_err("Not permitted to write ext  attr: 0x%x\n",
5603                                   fp->daccess);
5604                         return -EACCES;
5605                 }
5606
5607                 return smb2_set_ea((struct smb2_ea_info *)buf,
5608                                    &fp->filp->f_path);
5609         }
5610
5611         case FILE_POSITION_INFORMATION:
5612                 return set_file_position_info(fp, buf);
5613
5614         case FILE_MODE_INFORMATION:
5615                 return set_file_mode_info(fp, buf);
5616         }
5617
5618         ksmbd_err("Unimplemented Fileinfoclass :%d\n", info_class);
5619         return -EOPNOTSUPP;
5620 }
5621
5622 static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info,
5623                 char *buffer, int buf_len)
5624 {
5625         struct smb_ntsd *pntsd = (struct smb_ntsd *)buffer;
5626
5627         fp->saccess |= FILE_SHARE_DELETE_LE;
5628
5629         return set_info_sec(fp->conn, fp->tcon, fp->filp->f_path.dentry, pntsd,
5630                         buf_len, false);
5631 }
5632
5633 /**
5634  * smb2_set_info() - handler for smb2 set info command handler
5635  * @work:       smb work containing set info request buffer
5636  *
5637  * Return:      0 on success, otherwise error
5638  */
5639 int smb2_set_info(struct ksmbd_work *work)
5640 {
5641         struct smb2_set_info_req *req;
5642         struct smb2_set_info_rsp *rsp, *rsp_org;
5643         struct ksmbd_file *fp;
5644         int rc = 0;
5645         unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
5646
5647         ksmbd_debug(SMB, "Received set info request\n");
5648
5649         rsp_org = work->response_buf;
5650         if (work->next_smb2_rcv_hdr_off) {
5651                 req = REQUEST_BUF_NEXT(work);
5652                 rsp = RESPONSE_BUF_NEXT(work);
5653                 if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
5654                         ksmbd_debug(SMB, "Compound request set FID = %u\n",
5655                                         work->compound_fid);
5656                         id = work->compound_fid;
5657                         pid = work->compound_pfid;
5658                 }
5659         } else {
5660                 req = work->request_buf;
5661                 rsp = work->response_buf;
5662         }
5663
5664         if (!HAS_FILE_ID(id)) {
5665                 id = le64_to_cpu(req->VolatileFileId);
5666                 pid = le64_to_cpu(req->PersistentFileId);
5667         }
5668
5669         fp = ksmbd_lookup_fd_slow(work, id, pid);
5670         if (!fp) {
5671                 ksmbd_debug(SMB, "Invalid id for close: %u\n", id);
5672                 rc = -ENOENT;
5673                 goto err_out;
5674         }
5675
5676         switch (req->InfoType) {
5677         case SMB2_O_INFO_FILE:
5678                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n");
5679                 rc = smb2_set_info_file(work, fp, req->FileInfoClass,
5680                                         req->Buffer, work->tcon->share_conf);
5681                 break;
5682         case SMB2_O_INFO_SECURITY:
5683                 ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
5684                 rc = smb2_set_info_sec(fp,
5685                         le32_to_cpu(req->AdditionalInformation), req->Buffer,
5686                         le32_to_cpu(req->BufferLength));
5687                 break;
5688         default:
5689                 rc = -EOPNOTSUPP;
5690         }
5691
5692         if (rc < 0)
5693                 goto err_out;
5694
5695         rsp->StructureSize = cpu_to_le16(2);
5696         inc_rfc1001_len(rsp_org, 2);
5697         ksmbd_fd_put(work, fp);
5698         return 0;
5699
5700 err_out:
5701         if (rc == -EACCES || rc == -EPERM)
5702                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
5703         else if (rc == -EINVAL)
5704                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
5705         else if (rc == -ESHARE)
5706                 rsp->hdr.Status = STATUS_SHARING_VIOLATION;
5707         else if (rc == -ENOENT)
5708                 rsp->hdr.Status = STATUS_OBJECT_NAME_INVALID;
5709         else if (rc == -EBUSY || rc == -ENOTEMPTY)
5710                 rsp->hdr.Status = STATUS_DIRECTORY_NOT_EMPTY;
5711         else if (rc == -EAGAIN)
5712                 rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
5713         else if (rc == -EBADF || rc == -ESTALE)
5714                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
5715         else if (rc == -EEXIST)
5716                 rsp->hdr.Status = STATUS_OBJECT_NAME_COLLISION;
5717         else if (rsp->hdr.Status == 0 || rc == -EOPNOTSUPP)
5718                 rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
5719         smb2_set_err_rsp(work);
5720         ksmbd_fd_put(work, fp);
5721         ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n",
5722                         rc);
5723         return rc;
5724 }
5725
5726 /**
5727  * smb2_read_pipe() - handler for smb2 read from IPC pipe
5728  * @work:       smb work containing read IPC pipe command buffer
5729  *
5730  * Return:      0 on success, otherwise error
5731  */
5732 static noinline int smb2_read_pipe(struct ksmbd_work *work)
5733 {
5734         int nbytes = 0, err;
5735         u64 id;
5736         struct ksmbd_rpc_command *rpc_resp;
5737         struct smb2_read_req *req = work->request_buf;
5738         struct smb2_read_rsp *rsp = work->response_buf;
5739
5740         id = le64_to_cpu(req->VolatileFileId);
5741
5742         inc_rfc1001_len(rsp, 16);
5743         rpc_resp = ksmbd_rpc_read(work->sess, id);
5744         if (rpc_resp) {
5745                 if (rpc_resp->flags != KSMBD_RPC_OK) {
5746                         err = -EINVAL;
5747                         goto out;
5748                 }
5749
5750                 work->aux_payload_buf =
5751                         kvmalloc(rpc_resp->payload_sz, GFP_KERNEL | __GFP_ZERO);
5752                 if (!work->aux_payload_buf) {
5753                         err = -ENOMEM;
5754                         goto out;
5755                 }
5756
5757                 memcpy(work->aux_payload_buf, rpc_resp->payload,
5758                         rpc_resp->payload_sz);
5759
5760                 nbytes = rpc_resp->payload_sz;
5761                 work->resp_hdr_sz = get_rfc1002_len(rsp) + 4;
5762                 work->aux_payload_sz = nbytes;
5763                 kvfree(rpc_resp);
5764         }
5765
5766         rsp->StructureSize = cpu_to_le16(17);
5767         rsp->DataOffset = 80;
5768         rsp->Reserved = 0;
5769         rsp->DataLength = cpu_to_le32(nbytes);
5770         rsp->DataRemaining = 0;
5771         rsp->Reserved2 = 0;
5772         inc_rfc1001_len(rsp, nbytes);
5773         return 0;
5774
5775 out:
5776         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
5777         smb2_set_err_rsp(work);
5778         kvfree(rpc_resp);
5779         return err;
5780 }
5781
5782 static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
5783                 struct smb2_read_req *req, void *data_buf, size_t length)
5784 {
5785         struct smb2_buffer_desc_v1 *desc =
5786                 (struct smb2_buffer_desc_v1 *)&req->Buffer[0];
5787         int err;
5788
5789         if (work->conn->dialect == SMB30_PROT_ID &&
5790             req->Channel != SMB2_CHANNEL_RDMA_V1)
5791                 return -EINVAL;
5792
5793         if (req->ReadChannelInfoOffset == 0 ||
5794             le16_to_cpu(req->ReadChannelInfoLength) < sizeof(*desc))
5795                 return -EINVAL;
5796
5797         work->need_invalidate_rkey =
5798                 (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE);
5799         work->remote_key = le32_to_cpu(desc->token);
5800
5801         err = ksmbd_conn_rdma_write(work->conn, data_buf, length,
5802                         le32_to_cpu(desc->token), le64_to_cpu(desc->offset),
5803                         le32_to_cpu(desc->length));
5804         if (err)
5805                 return err;
5806
5807         return length;
5808 }
5809
5810 /**
5811  * smb2_read() - handler for smb2 read from file
5812  * @work:       smb work containing read command buffer
5813  *
5814  * Return:      0 on success, otherwise error
5815  */
5816 int smb2_read(struct ksmbd_work *work)
5817 {
5818         struct ksmbd_conn *conn = work->conn;
5819         struct smb2_read_req *req;
5820         struct smb2_read_rsp *rsp, *rsp_org;
5821         struct ksmbd_file *fp;
5822         loff_t offset;
5823         size_t length, mincount;
5824         ssize_t nbytes = 0, remain_bytes = 0;
5825         int err = 0;
5826
5827         rsp_org = work->response_buf;
5828         WORK_BUFFERS(work, req, rsp);
5829
5830         if (test_share_config_flag(work->tcon->share_conf,
5831                                    KSMBD_SHARE_FLAG_PIPE)) {
5832                 ksmbd_debug(SMB, "IPC pipe read request\n");
5833                 return smb2_read_pipe(work);
5834         }
5835
5836         fp = ksmbd_lookup_fd_slow(work,
5837                         le64_to_cpu(req->VolatileFileId),
5838                         le64_to_cpu(req->PersistentFileId));
5839         if (!fp) {
5840                 err = -ENOENT;
5841                 goto out;
5842         }
5843
5844         if (!(fp->daccess & (FILE_READ_DATA_LE | FILE_READ_ATTRIBUTES_LE))) {
5845                 ksmbd_err("Not permitted to read : 0x%x\n", fp->daccess);
5846                 err = -EACCES;
5847                 goto out;
5848         }
5849
5850         offset = le64_to_cpu(req->Offset);
5851         length = le32_to_cpu(req->Length);
5852         mincount = le32_to_cpu(req->MinimumCount);
5853
5854         if (length > conn->vals->max_read_size) {
5855                 ksmbd_debug(SMB, "limiting read size to max size(%u)\n",
5856                             conn->vals->max_read_size);
5857                 err = -EINVAL;
5858                 goto out;
5859         }
5860
5861         ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n", FP_FILENAME(fp),
5862                 offset, length);
5863
5864         if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF) {
5865                 work->aux_payload_buf =
5866                         ksmbd_find_buffer(conn->vals->max_read_size);
5867                 work->set_read_buf = true;
5868         } else {
5869                 work->aux_payload_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO);
5870         }
5871         if (!work->aux_payload_buf) {
5872                 err = -ENOMEM;
5873                 goto out;
5874         }
5875
5876         nbytes = ksmbd_vfs_read(work, fp, length, &offset);
5877         if (nbytes < 0) {
5878                 err = nbytes;
5879                 goto out;
5880         }
5881
5882         if ((nbytes == 0 && length != 0) || nbytes < mincount) {
5883                 if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF)
5884                         ksmbd_release_buffer(work->aux_payload_buf);
5885                 else
5886                         kvfree(work->aux_payload_buf);
5887                 work->aux_payload_buf = NULL;
5888                 rsp->hdr.Status = STATUS_END_OF_FILE;
5889                 smb2_set_err_rsp(work);
5890                 ksmbd_fd_put(work, fp);
5891                 return 0;
5892         }
5893
5894         ksmbd_debug(SMB, "nbytes %zu, offset %lld mincount %zu\n",
5895                                                 nbytes, offset, mincount);
5896
5897         if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ||
5898             req->Channel == SMB2_CHANNEL_RDMA_V1) {
5899                 /* write data to the client using rdma channel */
5900                 remain_bytes = smb2_read_rdma_channel(work, req,
5901                                                 work->aux_payload_buf, nbytes);
5902                 if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF)
5903                         ksmbd_release_buffer(work->aux_payload_buf);
5904                 else
5905                         kvfree(work->aux_payload_buf);
5906                 work->aux_payload_buf = NULL;
5907
5908                 nbytes = 0;
5909                 if (remain_bytes < 0) {
5910                         err = (int)remain_bytes;
5911                         goto out;
5912                 }
5913         }
5914
5915         rsp->StructureSize = cpu_to_le16(17);
5916         rsp->DataOffset = 80;
5917         rsp->Reserved = 0;
5918         rsp->DataLength = cpu_to_le32(nbytes);
5919         rsp->DataRemaining = cpu_to_le32(remain_bytes);
5920         rsp->Reserved2 = 0;
5921         inc_rfc1001_len(rsp_org, 16);
5922         work->resp_hdr_sz = get_rfc1002_len(rsp_org) + 4;
5923         work->aux_payload_sz = nbytes;
5924         inc_rfc1001_len(rsp_org, nbytes);
5925         ksmbd_fd_put(work, fp);
5926         return 0;
5927
5928 out:
5929         if (err) {
5930                 if (err == -EISDIR)
5931                         rsp->hdr.Status = STATUS_INVALID_DEVICE_REQUEST;
5932                 else if (err == -EAGAIN)
5933                         rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
5934                 else if (err == -ENOENT)
5935                         rsp->hdr.Status = STATUS_FILE_CLOSED;
5936                 else if (err == -EACCES)
5937                         rsp->hdr.Status = STATUS_ACCESS_DENIED;
5938                 else if (err == -ESHARE)
5939                         rsp->hdr.Status = STATUS_SHARING_VIOLATION;
5940                 else if (err == -EINVAL)
5941                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
5942                 else
5943                         rsp->hdr.Status = STATUS_INVALID_HANDLE;
5944
5945                 smb2_set_err_rsp(work);
5946         }
5947         ksmbd_fd_put(work, fp);
5948         return err;
5949 }
5950
5951 /**
5952  * smb2_write_pipe() - handler for smb2 write on IPC pipe
5953  * @work:       smb work containing write IPC pipe command buffer
5954  *
5955  * Return:      0 on success, otherwise error
5956  */
5957 static noinline int smb2_write_pipe(struct ksmbd_work *work)
5958 {
5959         struct smb2_write_req *req = work->request_buf;
5960         struct smb2_write_rsp *rsp = work->response_buf;
5961         struct ksmbd_rpc_command *rpc_resp;
5962         u64 id = 0;
5963         int err = 0, ret = 0;
5964         char *data_buf;
5965         size_t length;
5966
5967         length = le32_to_cpu(req->Length);
5968         id = le64_to_cpu(req->VolatileFileId);
5969
5970         if (le16_to_cpu(req->DataOffset) ==
5971             (offsetof(struct smb2_write_req, Buffer) - 4)) {
5972                 data_buf = (char *)&req->Buffer[0];
5973         } else {
5974                 if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) ||
5975                     (le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) {
5976                         ksmbd_err("invalid write data offset %u, smb_len %u\n",
5977                                 le16_to_cpu(req->DataOffset), get_rfc1002_len(req));
5978                         err = -EINVAL;
5979                         goto out;
5980                 }
5981
5982                 data_buf = (char *)(((char *)&req->hdr.ProtocolId) +
5983                                 le16_to_cpu(req->DataOffset));
5984         }
5985
5986         rpc_resp = ksmbd_rpc_write(work->sess, id, data_buf, length);
5987         if (rpc_resp) {
5988                 if (rpc_resp->flags == KSMBD_RPC_ENOTIMPLEMENTED) {
5989                         rsp->hdr.Status = STATUS_NOT_SUPPORTED;
5990                         kvfree(rpc_resp);
5991                         smb2_set_err_rsp(work);
5992                         return -EOPNOTSUPP;
5993                 }
5994                 if (rpc_resp->flags != KSMBD_RPC_OK) {
5995                         rsp->hdr.Status = STATUS_INVALID_HANDLE;
5996                         smb2_set_err_rsp(work);
5997                         kvfree(rpc_resp);
5998                         return ret;
5999                 }
6000                 kvfree(rpc_resp);
6001         }
6002
6003         rsp->StructureSize = cpu_to_le16(17);
6004         rsp->DataOffset = 0;
6005         rsp->Reserved = 0;
6006         rsp->DataLength = cpu_to_le32(length);
6007         rsp->DataRemaining = 0;
6008         rsp->Reserved2 = 0;
6009         inc_rfc1001_len(rsp, 16);
6010         return 0;
6011 out:
6012         if (err) {
6013                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
6014                 smb2_set_err_rsp(work);
6015         }
6016
6017         return err;
6018 }
6019
6020 static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
6021                 struct smb2_write_req *req, struct ksmbd_file *fp,
6022                 loff_t offset, size_t length, bool sync)
6023 {
6024         struct smb2_buffer_desc_v1 *desc;
6025         char *data_buf;
6026         int ret;
6027         ssize_t nbytes;
6028
6029         desc = (struct smb2_buffer_desc_v1 *)&req->Buffer[0];
6030
6031         if (work->conn->dialect == SMB30_PROT_ID &&
6032             req->Channel != SMB2_CHANNEL_RDMA_V1)
6033                 return -EINVAL;
6034
6035         if (req->Length != 0 || req->DataOffset != 0)
6036                 return -EINVAL;
6037
6038         if (req->WriteChannelInfoOffset == 0 ||
6039             le16_to_cpu(req->WriteChannelInfoLength) < sizeof(*desc))
6040                 return -EINVAL;
6041
6042         work->need_invalidate_rkey =
6043                 (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE);
6044         work->remote_key = le32_to_cpu(desc->token);
6045
6046         data_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO);
6047         if (!data_buf)
6048                 return -ENOMEM;
6049
6050         ret = ksmbd_conn_rdma_read(work->conn, data_buf, length,
6051                                 le32_to_cpu(desc->token),
6052                                 le64_to_cpu(desc->offset),
6053                                 le32_to_cpu(desc->length));
6054         if (ret < 0) {
6055                 kvfree(data_buf);
6056                 return ret;
6057         }
6058
6059         ret = ksmbd_vfs_write(work, fp, data_buf, length, &offset, sync, &nbytes);
6060         kvfree(data_buf);
6061         if (ret < 0)
6062                 return ret;
6063
6064         return nbytes;
6065 }
6066
6067 /**
6068  * smb2_write() - handler for smb2 write from file
6069  * @work:       smb work containing write command buffer
6070  *
6071  * Return:      0 on success, otherwise error
6072  */
6073 int smb2_write(struct ksmbd_work *work)
6074 {
6075         struct smb2_write_req *req;
6076         struct smb2_write_rsp *rsp, *rsp_org;
6077         struct ksmbd_file *fp = NULL;
6078         loff_t offset;
6079         size_t length;
6080         ssize_t nbytes;
6081         char *data_buf;
6082         bool writethrough = false;
6083         int err = 0;
6084
6085         rsp_org = work->response_buf;
6086         WORK_BUFFERS(work, req, rsp);
6087
6088         if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) {
6089                 ksmbd_debug(SMB, "IPC pipe write request\n");
6090                 return smb2_write_pipe(work);
6091         }
6092
6093         if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
6094                 ksmbd_debug(SMB, "User does not have write permission\n");
6095                 err = -EACCES;
6096                 goto out;
6097         }
6098
6099         fp = ksmbd_lookup_fd_slow(work, le64_to_cpu(req->VolatileFileId),
6100                 le64_to_cpu(req->PersistentFileId));
6101         if (!fp) {
6102                 err = -ENOENT;
6103                 goto out;
6104         }
6105
6106         if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_READ_ATTRIBUTES_LE))) {
6107                 ksmbd_err("Not permitted to write : 0x%x\n", fp->daccess);
6108                 err = -EACCES;
6109                 goto out;
6110         }
6111
6112         offset = le64_to_cpu(req->Offset);
6113         length = le32_to_cpu(req->Length);
6114
6115         if (length > work->conn->vals->max_write_size) {
6116                 ksmbd_debug(SMB, "limiting write size to max size(%u)\n",
6117                             work->conn->vals->max_write_size);
6118                 err = -EINVAL;
6119                 goto out;
6120         }
6121
6122         if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH)
6123                 writethrough = true;
6124
6125         if (req->Channel != SMB2_CHANNEL_RDMA_V1 &&
6126             req->Channel != SMB2_CHANNEL_RDMA_V1_INVALIDATE) {
6127                 if (le16_to_cpu(req->DataOffset) ==
6128                                 (offsetof(struct smb2_write_req, Buffer) - 4)) {
6129                         data_buf = (char *)&req->Buffer[0];
6130                 } else {
6131                         if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) ||
6132                             (le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) {
6133                                 ksmbd_err("invalid write data offset %u, smb_len %u\n",
6134                                                 le16_to_cpu(req->DataOffset),
6135                                                 get_rfc1002_len(req));
6136                                 err = -EINVAL;
6137                                 goto out;
6138                         }
6139
6140                         data_buf = (char *)(((char *)&req->hdr.ProtocolId) +
6141                                         le16_to_cpu(req->DataOffset));
6142                 }
6143
6144                 ksmbd_debug(SMB, "flags %u\n", le32_to_cpu(req->Flags));
6145                 if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH)
6146                         writethrough = true;
6147
6148                 ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n",
6149                         FP_FILENAME(fp), offset, length);
6150                 err = ksmbd_vfs_write(work, fp, data_buf, length, &offset,
6151                                       writethrough, &nbytes);
6152                 if (err < 0)
6153                         goto out;
6154         } else {
6155                 /* read data from the client using rdma channel, and
6156                  * write the data.
6157                  */
6158                 nbytes = smb2_write_rdma_channel(work, req, fp, offset,
6159                                         le32_to_cpu(req->RemainingBytes),
6160                                         writethrough);
6161                 if (nbytes < 0) {
6162                         err = (int)nbytes;
6163                         goto out;
6164                 }
6165         }
6166
6167         rsp->StructureSize = cpu_to_le16(17);
6168         rsp->DataOffset = 0;
6169         rsp->Reserved = 0;
6170         rsp->DataLength = cpu_to_le32(nbytes);
6171         rsp->DataRemaining = 0;
6172         rsp->Reserved2 = 0;
6173         inc_rfc1001_len(rsp_org, 16);
6174         ksmbd_fd_put(work, fp);
6175         return 0;
6176
6177 out:
6178         if (err == -EAGAIN)
6179                 rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
6180         else if (err == -ENOSPC || err == -EFBIG)
6181                 rsp->hdr.Status = STATUS_DISK_FULL;
6182         else if (err == -ENOENT)
6183                 rsp->hdr.Status = STATUS_FILE_CLOSED;
6184         else if (err == -EACCES)
6185                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
6186         else if (err == -ESHARE)
6187                 rsp->hdr.Status = STATUS_SHARING_VIOLATION;
6188         else if (err == -EINVAL)
6189                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6190         else
6191                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
6192
6193         smb2_set_err_rsp(work);
6194         ksmbd_fd_put(work, fp);
6195         return err;
6196 }
6197
6198 /**
6199  * smb2_flush() - handler for smb2 flush file - fsync
6200  * @work:       smb work containing flush command buffer
6201  *
6202  * Return:      0 on success, otherwise error
6203  */
6204 int smb2_flush(struct ksmbd_work *work)
6205 {
6206         struct smb2_flush_req *req;
6207         struct smb2_flush_rsp *rsp, *rsp_org;
6208         int err;
6209
6210         rsp_org = work->response_buf;
6211         WORK_BUFFERS(work, req, rsp);
6212
6213         ksmbd_debug(SMB, "SMB2_FLUSH called for fid %llu\n",
6214                         le64_to_cpu(req->VolatileFileId));
6215
6216         err = ksmbd_vfs_fsync(work,
6217                               le64_to_cpu(req->VolatileFileId),
6218                               le64_to_cpu(req->PersistentFileId));
6219         if (err)
6220                 goto out;
6221
6222         rsp->StructureSize = cpu_to_le16(4);
6223         rsp->Reserved = 0;
6224         inc_rfc1001_len(rsp_org, 4);
6225         return 0;
6226
6227 out:
6228         if (err) {
6229                 rsp->hdr.Status = STATUS_INVALID_HANDLE;
6230                 smb2_set_err_rsp(work);
6231         }
6232
6233         return err;
6234 }
6235
6236 /**
6237  * smb2_cancel() - handler for smb2 cancel command
6238  * @work:       smb work containing cancel command buffer
6239  *
6240  * Return:      0 on success, otherwise error
6241  */
6242 int smb2_cancel(struct ksmbd_work *work)
6243 {
6244         struct ksmbd_conn *conn = work->conn;
6245         struct smb2_hdr *hdr = work->request_buf;
6246         struct smb2_hdr *chdr;
6247         struct ksmbd_work *cancel_work = NULL;
6248         struct list_head *tmp;
6249         int canceled = 0;
6250         struct list_head *command_list;
6251
6252         ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
6253                 hdr->MessageId, hdr->Flags);
6254
6255         if (hdr->Flags & SMB2_FLAGS_ASYNC_COMMAND) {
6256                 command_list = &conn->async_requests;
6257
6258                 spin_lock(&conn->request_lock);
6259                 list_for_each(tmp, command_list) {
6260                         cancel_work = list_entry(tmp, struct ksmbd_work,
6261                                         async_request_entry);
6262                         chdr = cancel_work->request_buf;
6263
6264                         if (cancel_work->async_id !=
6265                             le64_to_cpu(hdr->Id.AsyncId))
6266                                 continue;
6267
6268                         ksmbd_debug(SMB,
6269                                 "smb2 with AsyncId %llu cancelled command = 0x%x\n",
6270                                 le64_to_cpu(hdr->Id.AsyncId),
6271                                 le16_to_cpu(chdr->Command));
6272                         canceled = 1;
6273                         break;
6274                 }
6275                 spin_unlock(&conn->request_lock);
6276         } else {
6277                 command_list = &conn->requests;
6278
6279                 spin_lock(&conn->request_lock);
6280                 list_for_each(tmp, command_list) {
6281                         cancel_work = list_entry(tmp, struct ksmbd_work,
6282                                         request_entry);
6283                         chdr = cancel_work->request_buf;
6284
6285                         if (chdr->MessageId != hdr->MessageId ||
6286                             cancel_work == work)
6287                                 continue;
6288
6289                         ksmbd_debug(SMB,
6290                                 "smb2 with mid %llu cancelled command = 0x%x\n",
6291                                 le64_to_cpu(hdr->MessageId),
6292                                 le16_to_cpu(chdr->Command));
6293                         canceled = 1;
6294                         break;
6295                 }
6296                 spin_unlock(&conn->request_lock);
6297         }
6298
6299         if (canceled) {
6300                 cancel_work->state = KSMBD_WORK_CANCELLED;
6301                 if (cancel_work->cancel_fn)
6302                         cancel_work->cancel_fn(cancel_work->cancel_argv);
6303         }
6304
6305         /* For SMB2_CANCEL command itself send no response*/
6306         work->send_no_response = 1;
6307         return 0;
6308 }
6309
6310 struct file_lock *smb_flock_init(struct file *f)
6311 {
6312         struct file_lock *fl;
6313
6314         fl = locks_alloc_lock();
6315         if (!fl)
6316                 goto out;
6317
6318         locks_init_lock(fl);
6319
6320         fl->fl_owner = f;
6321         fl->fl_pid = current->tgid;
6322         fl->fl_file = f;
6323         fl->fl_flags = FL_POSIX;
6324         fl->fl_ops = NULL;
6325         fl->fl_lmops = NULL;
6326
6327 out:
6328         return fl;
6329 }
6330
6331 static int smb2_set_flock_flags(struct file_lock *flock, int flags)
6332 {
6333         int cmd = -EINVAL;
6334
6335         /* Checking for wrong flag combination during lock request*/
6336         switch (flags) {
6337         case SMB2_LOCKFLAG_SHARED:
6338                 ksmbd_debug(SMB, "received shared request\n");
6339                 cmd = F_SETLKW;
6340                 flock->fl_type = F_RDLCK;
6341                 flock->fl_flags |= FL_SLEEP;
6342                 break;
6343         case SMB2_LOCKFLAG_EXCLUSIVE:
6344                 ksmbd_debug(SMB, "received exclusive request\n");
6345                 cmd = F_SETLKW;
6346                 flock->fl_type = F_WRLCK;
6347                 flock->fl_flags |= FL_SLEEP;
6348                 break;
6349         case SMB2_LOCKFLAG_SHARED | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
6350                 ksmbd_debug(SMB,
6351                         "received shared & fail immediately request\n");
6352                 cmd = F_SETLK;
6353                 flock->fl_type = F_RDLCK;
6354                 break;
6355         case SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
6356                 ksmbd_debug(SMB,
6357                         "received exclusive & fail immediately request\n");
6358                 cmd = F_SETLK;
6359                 flock->fl_type = F_WRLCK;
6360                 break;
6361         case SMB2_LOCKFLAG_UNLOCK:
6362                 ksmbd_debug(SMB, "received unlock request\n");
6363                 flock->fl_type = F_UNLCK;
6364                 cmd = 0;
6365                 break;
6366         }
6367
6368         return cmd;
6369 }
6370
6371 static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock,
6372                 unsigned int cmd, int flags, struct list_head *lock_list)
6373 {
6374         struct ksmbd_lock *lock;
6375
6376         lock = kzalloc(sizeof(struct ksmbd_lock), GFP_KERNEL);
6377         if (!lock)
6378                 return NULL;
6379
6380         lock->cmd = cmd;
6381         lock->fl = flock;
6382         lock->start = flock->fl_start;
6383         lock->end = flock->fl_end;
6384         lock->flags = flags;
6385         if (lock->start == lock->end)
6386                 lock->zero_len = 1;
6387         INIT_LIST_HEAD(&lock->llist);
6388         INIT_LIST_HEAD(&lock->glist);
6389         list_add_tail(&lock->llist, lock_list);
6390
6391         return lock;
6392 }
6393
6394 static void smb2_remove_blocked_lock(void **argv)
6395 {
6396         struct file_lock *flock = (struct file_lock *)argv[0];
6397
6398         ksmbd_vfs_posix_lock_unblock(flock);
6399         wake_up(&flock->fl_wait);
6400 }
6401
6402 static inline bool lock_defer_pending(struct file_lock *fl)
6403 {
6404         /* check pending lock waiters */
6405         return waitqueue_active(&fl->fl_wait);
6406 }
6407
6408 /**
6409  * smb2_lock() - handler for smb2 file lock command
6410  * @work:       smb work containing lock command buffer
6411  *
6412  * Return:      0 on success, otherwise error
6413  */
6414 int smb2_lock(struct ksmbd_work *work)
6415 {
6416         struct smb2_lock_req *req = work->request_buf;
6417         struct smb2_lock_rsp *rsp = work->response_buf;
6418         struct smb2_lock_element *lock_ele;
6419         struct ksmbd_file *fp = NULL;
6420         struct file_lock *flock = NULL;
6421         struct file *filp = NULL;
6422         int lock_count;
6423         int flags = 0;
6424         int cmd = 0;
6425         int err = 0, i;
6426         u64 lock_start, lock_length;
6427         struct ksmbd_lock *smb_lock = NULL, *cmp_lock, *tmp;
6428         int nolock = 0;
6429         LIST_HEAD(lock_list);
6430         LIST_HEAD(rollback_list);
6431         int prior_lock = 0;
6432
6433         ksmbd_debug(SMB, "Received lock request\n");
6434         fp = ksmbd_lookup_fd_slow(work,
6435                 le64_to_cpu(req->VolatileFileId),
6436                 le64_to_cpu(req->PersistentFileId));
6437         if (!fp) {
6438                 ksmbd_debug(SMB, "Invalid file id for lock : %llu\n",
6439                                 le64_to_cpu(req->VolatileFileId));
6440                 rsp->hdr.Status = STATUS_FILE_CLOSED;
6441                 goto out2;
6442         }
6443
6444         filp = fp->filp;
6445         lock_count = le16_to_cpu(req->LockCount);
6446         lock_ele = req->locks;
6447
6448         ksmbd_debug(SMB, "lock count is %d\n", lock_count);
6449         if (!lock_count)  {
6450                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6451                 goto out2;
6452         }
6453
6454         for (i = 0; i < lock_count; i++) {
6455                 flags = le32_to_cpu(lock_ele[i].Flags);
6456
6457                 flock = smb_flock_init(filp);
6458                 if (!flock) {
6459                         rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
6460                         goto out;
6461                 }
6462
6463                 cmd = smb2_set_flock_flags(flock, flags);
6464
6465                 lock_start = le64_to_cpu(lock_ele[i].Offset);
6466                 lock_length = le64_to_cpu(lock_ele[i].Length);
6467                 if (lock_start > U64_MAX - lock_length) {
6468                         ksmbd_err("Invalid lock range requested\n");
6469                         rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
6470                         goto out;
6471                 }
6472
6473                 if (lock_start > OFFSET_MAX)
6474                         flock->fl_start = OFFSET_MAX;
6475                 else
6476                         flock->fl_start = lock_start;
6477
6478                 lock_length = le64_to_cpu(lock_ele[i].Length);
6479                 if (lock_length > OFFSET_MAX - flock->fl_start)
6480                         lock_length = OFFSET_MAX - flock->fl_start;
6481
6482                 flock->fl_end = flock->fl_start + lock_length;
6483
6484                 if (flock->fl_end < flock->fl_start) {
6485                         ksmbd_debug(SMB,
6486                                 "the end offset(%llx) is smaller than the start offset(%llx)\n",
6487                                 flock->fl_end, flock->fl_start);
6488                         rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
6489                         goto out;
6490                 }
6491
6492                 /* Check conflict locks in one request */
6493                 list_for_each_entry(cmp_lock, &lock_list, llist) {
6494                         if (cmp_lock->fl->fl_start <= flock->fl_start &&
6495                             cmp_lock->fl->fl_end >= flock->fl_end) {
6496                                 if (cmp_lock->fl->fl_type != F_UNLCK &&
6497                                     flock->fl_type != F_UNLCK) {
6498                                         ksmbd_err("conflict two locks in one request\n");
6499                                         rsp->hdr.Status =
6500                                                 STATUS_INVALID_PARAMETER;
6501                                         goto out;
6502                                 }
6503                         }
6504                 }
6505
6506                 smb_lock = smb2_lock_init(flock, cmd, flags, &lock_list);
6507                 if (!smb_lock) {
6508                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6509                         goto out;
6510                 }
6511         }
6512
6513         list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) {
6514                 if (smb_lock->cmd < 0) {
6515                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6516                         goto out;
6517                 }
6518
6519                 if (!(smb_lock->flags & SMB2_LOCKFLAG_MASK)) {
6520                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6521                         goto out;
6522                 }
6523
6524                 if ((prior_lock & (SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_SHARED) &&
6525                      smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) ||
6526                     (prior_lock == SMB2_LOCKFLAG_UNLOCK &&
6527                      !(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK))) {
6528                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6529                         goto out;
6530                 }
6531
6532                 prior_lock = smb_lock->flags;
6533
6534                 if (!(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) &&
6535                     !(smb_lock->flags & SMB2_LOCKFLAG_FAIL_IMMEDIATELY))
6536                         goto no_check_gl;
6537
6538                 nolock = 1;
6539                 /* check locks in global list */
6540                 list_for_each_entry(cmp_lock, &global_lock_list, glist) {
6541                         if (file_inode(cmp_lock->fl->fl_file) !=
6542                             file_inode(smb_lock->fl->fl_file))
6543                                 continue;
6544
6545                         if (smb_lock->fl->fl_type == F_UNLCK) {
6546                                 if (cmp_lock->fl->fl_file == smb_lock->fl->fl_file &&
6547                                     cmp_lock->start == smb_lock->start &&
6548                                     cmp_lock->end == smb_lock->end &&
6549                                     !lock_defer_pending(cmp_lock->fl)) {
6550                                         nolock = 0;
6551                                         locks_free_lock(cmp_lock->fl);
6552                                         list_del(&cmp_lock->glist);
6553                                         kfree(cmp_lock);
6554                                         break;
6555                                 }
6556                                 continue;
6557                         }
6558
6559                         if (cmp_lock->fl->fl_file == smb_lock->fl->fl_file) {
6560                                 if (smb_lock->flags & SMB2_LOCKFLAG_SHARED)
6561                                         continue;
6562                         } else {
6563                                 if (cmp_lock->flags & SMB2_LOCKFLAG_SHARED)
6564                                         continue;
6565                         }
6566
6567                         /* check zero byte lock range */
6568                         if (cmp_lock->zero_len && !smb_lock->zero_len &&
6569                             cmp_lock->start > smb_lock->start &&
6570                             cmp_lock->start < smb_lock->end) {
6571                                 ksmbd_err("previous lock conflict with zero byte lock range\n");
6572                                 rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
6573                                         goto out;
6574                         }
6575
6576                         if (smb_lock->zero_len && !cmp_lock->zero_len &&
6577                             smb_lock->start > cmp_lock->start &&
6578                             smb_lock->start < cmp_lock->end) {
6579                                 ksmbd_err("current lock conflict with zero byte lock range\n");
6580                                 rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
6581                                         goto out;
6582                         }
6583
6584                         if (((cmp_lock->start <= smb_lock->start &&
6585                               cmp_lock->end > smb_lock->start) ||
6586                              (cmp_lock->start < smb_lock->end && cmp_lock->end >= smb_lock->end)) &&
6587                             !cmp_lock->zero_len && !smb_lock->zero_len) {
6588                                 ksmbd_err("Not allow lock operation on exclusive lock range\n");
6589                                 rsp->hdr.Status =
6590                                         STATUS_LOCK_NOT_GRANTED;
6591                                 goto out;
6592                         }
6593                 }
6594
6595                 if (smb_lock->fl->fl_type == F_UNLCK && nolock) {
6596                         ksmbd_err("Try to unlock nolocked range\n");
6597                         rsp->hdr.Status = STATUS_RANGE_NOT_LOCKED;
6598                         goto out;
6599                 }
6600
6601 no_check_gl:
6602                 if (smb_lock->zero_len) {
6603                         err = 0;
6604                         goto skip;
6605                 }
6606
6607                 flock = smb_lock->fl;
6608                 list_del(&smb_lock->llist);
6609 retry:
6610                 err = ksmbd_vfs_lock(filp, smb_lock->cmd, flock);
6611 skip:
6612                 if (flags & SMB2_LOCKFLAG_UNLOCK) {
6613                         if (!err) {
6614                                 ksmbd_debug(SMB, "File unlocked\n");
6615                         } else if (err == -ENOENT) {
6616                                 rsp->hdr.Status = STATUS_NOT_LOCKED;
6617                                 goto out;
6618                         }
6619                         locks_free_lock(flock);
6620                         kfree(smb_lock);
6621                 } else {
6622                         if (err == FILE_LOCK_DEFERRED) {
6623                                 void **argv;
6624
6625                                 ksmbd_debug(SMB,
6626                                         "would have to wait for getting lock\n");
6627                                 list_add_tail(&smb_lock->glist,
6628                                         &global_lock_list);
6629                                 list_add(&smb_lock->llist, &rollback_list);
6630
6631                                 argv = kmalloc(sizeof(void *), GFP_KERNEL);
6632                                 if (!argv) {
6633                                         err = -ENOMEM;
6634                                         goto out;
6635                                 }
6636                                 argv[0] = flock;
6637
6638                                 err = setup_async_work(work,
6639                                         smb2_remove_blocked_lock, argv);
6640                                 if (err) {
6641                                         rsp->hdr.Status =
6642                                            STATUS_INSUFFICIENT_RESOURCES;
6643                                         goto out;
6644                                 }
6645                                 spin_lock(&fp->f_lock);
6646                                 list_add(&work->fp_entry, &fp->blocked_works);
6647                                 spin_unlock(&fp->f_lock);
6648
6649                                 smb2_send_interim_resp(work, STATUS_PENDING);
6650
6651                                 err = ksmbd_vfs_posix_lock_wait(flock);
6652
6653                                 if (!WORK_ACTIVE(work)) {
6654                                         list_del(&smb_lock->llist);
6655                                         list_del(&smb_lock->glist);
6656                                         locks_free_lock(flock);
6657
6658                                         if (WORK_CANCELLED(work)) {
6659                                                 spin_lock(&fp->f_lock);
6660                                                 list_del(&work->fp_entry);
6661                                                 spin_unlock(&fp->f_lock);
6662                                                 rsp->hdr.Status =
6663                                                         STATUS_CANCELLED;
6664                                                 kfree(smb_lock);
6665                                                 smb2_send_interim_resp(work,
6666                                                         STATUS_CANCELLED);
6667                                                 work->send_no_response = 1;
6668                                                 goto out;
6669                                         }
6670                                         init_smb2_rsp_hdr(work);
6671                                         smb2_set_err_rsp(work);
6672                                         rsp->hdr.Status =
6673                                                 STATUS_RANGE_NOT_LOCKED;
6674                                         kfree(smb_lock);
6675                                         goto out2;
6676                                 }
6677
6678                                 list_del(&smb_lock->llist);
6679                                 list_del(&smb_lock->glist);
6680                                 spin_lock(&fp->f_lock);
6681                                 list_del(&work->fp_entry);
6682                                 spin_unlock(&fp->f_lock);
6683                                 goto retry;
6684                         } else if (!err) {
6685                                 list_add_tail(&smb_lock->glist,
6686                                         &global_lock_list);
6687                                 list_add(&smb_lock->llist, &rollback_list);
6688                                 ksmbd_debug(SMB, "successful in taking lock\n");
6689                         } else {
6690                                 rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
6691                                 goto out;
6692                         }
6693                 }
6694         }
6695
6696         if (atomic_read(&fp->f_ci->op_count) > 1)
6697                 smb_break_all_oplock(work, fp);
6698
6699         rsp->StructureSize = cpu_to_le16(4);
6700         ksmbd_debug(SMB, "successful in taking lock\n");
6701         rsp->hdr.Status = STATUS_SUCCESS;
6702         rsp->Reserved = 0;
6703         inc_rfc1001_len(rsp, 4);
6704         ksmbd_fd_put(work, fp);
6705         return err;
6706
6707 out:
6708         list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) {
6709                 locks_free_lock(smb_lock->fl);
6710                 list_del(&smb_lock->llist);
6711                 kfree(smb_lock);
6712         }
6713
6714         list_for_each_entry_safe(smb_lock, tmp, &rollback_list, llist) {
6715                 struct file_lock *rlock = NULL;
6716
6717                 rlock = smb_flock_init(filp);
6718                 rlock->fl_type = F_UNLCK;
6719                 rlock->fl_start = smb_lock->start;
6720                 rlock->fl_end = smb_lock->end;
6721
6722                 err = ksmbd_vfs_lock(filp, 0, rlock);
6723                 if (err)
6724                         ksmbd_err("rollback unlock fail : %d\n", err);
6725                 list_del(&smb_lock->llist);
6726                 list_del(&smb_lock->glist);
6727                 locks_free_lock(smb_lock->fl);
6728                 locks_free_lock(rlock);
6729                 kfree(smb_lock);
6730         }
6731 out2:
6732         ksmbd_debug(SMB, "failed in taking lock(flags : %x)\n", flags);
6733         smb2_set_err_rsp(work);
6734         ksmbd_fd_put(work, fp);
6735         return 0;
6736 }
6737
6738 static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req,
6739                 struct smb2_ioctl_rsp *rsp)
6740 {
6741         struct copychunk_ioctl_req *ci_req;
6742         struct copychunk_ioctl_rsp *ci_rsp;
6743         struct ksmbd_file *src_fp = NULL, *dst_fp = NULL;
6744         struct srv_copychunk *chunks;
6745         unsigned int i, chunk_count, chunk_count_written = 0;
6746         unsigned int chunk_size_written = 0;
6747         loff_t total_size_written = 0;
6748         int ret, cnt_code;
6749
6750         cnt_code = le32_to_cpu(req->CntCode);
6751         ci_req = (struct copychunk_ioctl_req *)&req->Buffer[0];
6752         ci_rsp = (struct copychunk_ioctl_rsp *)&rsp->Buffer[0];
6753
6754         rsp->VolatileFileId = req->VolatileFileId;
6755         rsp->PersistentFileId = req->PersistentFileId;
6756         ci_rsp->ChunksWritten =
6757                 cpu_to_le32(ksmbd_server_side_copy_max_chunk_count());
6758         ci_rsp->ChunkBytesWritten =
6759                 cpu_to_le32(ksmbd_server_side_copy_max_chunk_size());
6760         ci_rsp->TotalBytesWritten =
6761                 cpu_to_le32(ksmbd_server_side_copy_max_total_size());
6762
6763         chunks = (struct srv_copychunk *)&ci_req->Chunks[0];
6764         chunk_count = le32_to_cpu(ci_req->ChunkCount);
6765         total_size_written = 0;
6766
6767         /* verify the SRV_COPYCHUNK_COPY packet */
6768         if (chunk_count > ksmbd_server_side_copy_max_chunk_count() ||
6769             le32_to_cpu(req->InputCount) <
6770              offsetof(struct copychunk_ioctl_req, Chunks) +
6771              chunk_count * sizeof(struct srv_copychunk)) {
6772                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6773                 return -EINVAL;
6774         }
6775
6776         for (i = 0; i < chunk_count; i++) {
6777                 if (le32_to_cpu(chunks[i].Length) == 0 ||
6778                     le32_to_cpu(chunks[i].Length) > ksmbd_server_side_copy_max_chunk_size())
6779                         break;
6780                 total_size_written += le32_to_cpu(chunks[i].Length);
6781         }
6782
6783         if (i < chunk_count ||
6784             total_size_written > ksmbd_server_side_copy_max_total_size()) {
6785                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6786                 return -EINVAL;
6787         }
6788
6789         src_fp = ksmbd_lookup_foreign_fd(work,
6790                         le64_to_cpu(ci_req->ResumeKey[0]));
6791         dst_fp = ksmbd_lookup_fd_slow(work,
6792                                  le64_to_cpu(req->VolatileFileId),
6793                                  le64_to_cpu(req->PersistentFileId));
6794         ret = -EINVAL;
6795         if (!src_fp ||
6796             src_fp->persistent_id != le64_to_cpu(ci_req->ResumeKey[1])) {
6797                 rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
6798                 goto out;
6799         }
6800
6801         if (!dst_fp) {
6802                 rsp->hdr.Status = STATUS_FILE_CLOSED;
6803                 goto out;
6804         }
6805
6806         /*
6807          * FILE_READ_DATA should only be included in
6808          * the FSCTL_COPYCHUNK case
6809          */
6810         if (cnt_code == FSCTL_COPYCHUNK && !(dst_fp->daccess &
6811                         (FILE_READ_DATA_LE | FILE_GENERIC_READ_LE))) {
6812                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
6813                 goto out;
6814         }
6815
6816         ret = ksmbd_vfs_copy_file_ranges(work, src_fp, dst_fp,
6817                         chunks, chunk_count,
6818                         &chunk_count_written, &chunk_size_written,
6819                         &total_size_written);
6820         if (ret < 0) {
6821                 if (ret == -EACCES)
6822                         rsp->hdr.Status = STATUS_ACCESS_DENIED;
6823                 if (ret == -EAGAIN)
6824                         rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
6825                 else if (ret == -EBADF)
6826                         rsp->hdr.Status = STATUS_INVALID_HANDLE;
6827                 else if (ret == -EFBIG || ret == -ENOSPC)
6828                         rsp->hdr.Status = STATUS_DISK_FULL;
6829                 else if (ret == -EINVAL)
6830                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6831                 else if (ret == -EISDIR)
6832                         rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
6833                 else if (ret == -E2BIG)
6834                         rsp->hdr.Status = STATUS_INVALID_VIEW_SIZE;
6835                 else
6836                         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
6837         }
6838
6839         ci_rsp->ChunksWritten = cpu_to_le32(chunk_count_written);
6840         ci_rsp->ChunkBytesWritten = cpu_to_le32(chunk_size_written);
6841         ci_rsp->TotalBytesWritten = cpu_to_le32(total_size_written);
6842 out:
6843         ksmbd_fd_put(work, src_fp);
6844         ksmbd_fd_put(work, dst_fp);
6845         return ret;
6846 }
6847
6848 static __be32 idev_ipv4_address(struct in_device *idev)
6849 {
6850         __be32 addr = 0;
6851
6852         struct in_ifaddr *ifa;
6853
6854         rcu_read_lock();
6855         in_dev_for_each_ifa_rcu(ifa, idev) {
6856                 if (ifa->ifa_flags & IFA_F_SECONDARY)
6857                         continue;
6858
6859                 addr = ifa->ifa_address;
6860                 break;
6861         }
6862         rcu_read_unlock();
6863         return addr;
6864 }
6865
6866 static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
6867                 struct smb2_ioctl_req *req, struct smb2_ioctl_rsp *rsp)
6868 {
6869         struct network_interface_info_ioctl_rsp *nii_rsp = NULL;
6870         int nbytes = 0;
6871         struct net_device *netdev;
6872         struct sockaddr_storage_rsp *sockaddr_storage;
6873         unsigned int flags;
6874         unsigned long long speed;
6875
6876         rtnl_lock();
6877         for_each_netdev(&init_net, netdev) {
6878                 if (unlikely(!netdev)) {
6879                         rtnl_unlock();
6880                         return -EINVAL;
6881                 }
6882
6883                 if (netdev->type == ARPHRD_LOOPBACK)
6884                         continue;
6885
6886                 flags = dev_get_flags(netdev);
6887                 if (!(flags & IFF_RUNNING))
6888                         continue;
6889
6890                 nii_rsp = (struct network_interface_info_ioctl_rsp *)
6891                                 &rsp->Buffer[nbytes];
6892                 nii_rsp->IfIndex = cpu_to_le32(netdev->ifindex);
6893
6894                 /* TODO: specify the RDMA capabilities */
6895                 if (netdev->num_tx_queues > 1)
6896                         nii_rsp->Capability = cpu_to_le32(RSS_CAPABLE);
6897                 else
6898                         nii_rsp->Capability = 0;
6899
6900                 nii_rsp->Next = cpu_to_le32(152);
6901                 nii_rsp->Reserved = 0;
6902
6903                 if (netdev->ethtool_ops->get_link_ksettings) {
6904                         struct ethtool_link_ksettings cmd;
6905
6906                         netdev->ethtool_ops->get_link_ksettings(netdev, &cmd);
6907                         speed = cmd.base.speed;
6908                 } else {
6909                         ksmbd_err("%s %s\n", netdev->name,
6910                                 "speed is unknown, defaulting to 1Gb/sec");
6911                         speed = SPEED_1000;
6912                 }
6913
6914                 speed *= 1000000;
6915                 nii_rsp->LinkSpeed = cpu_to_le64(speed);
6916
6917                 sockaddr_storage = (struct sockaddr_storage_rsp *)
6918                                         nii_rsp->SockAddr_Storage;
6919                 memset(sockaddr_storage, 0, 128);
6920
6921                 if (conn->peer_addr.ss_family == PF_INET) {
6922                         struct in_device *idev;
6923
6924                         sockaddr_storage->Family = cpu_to_le16(INTERNETWORK);
6925                         sockaddr_storage->addr4.Port = 0;
6926
6927                         idev = __in_dev_get_rtnl(netdev);
6928                         if (!idev)
6929                                 continue;
6930                         sockaddr_storage->addr4.IPv4address =
6931                                                 idev_ipv4_address(idev);
6932                 } else {
6933                         struct inet6_dev *idev6;
6934                         struct inet6_ifaddr *ifa;
6935                         __u8 *ipv6_addr = sockaddr_storage->addr6.IPv6address;
6936
6937                         sockaddr_storage->Family = cpu_to_le16(INTERNETWORKV6);
6938                         sockaddr_storage->addr6.Port = 0;
6939                         sockaddr_storage->addr6.FlowInfo = 0;
6940
6941                         idev6 = __in6_dev_get(netdev);
6942                         if (!idev6)
6943                                 continue;
6944
6945                         list_for_each_entry(ifa, &idev6->addr_list, if_list) {
6946                                 if (ifa->flags & (IFA_F_TENTATIVE |
6947                                                         IFA_F_DEPRECATED))
6948                                         continue;
6949                                 memcpy(ipv6_addr, ifa->addr.s6_addr, 16);
6950                                 break;
6951                         }
6952                         sockaddr_storage->addr6.ScopeId = 0;
6953                 }
6954
6955                 nbytes += sizeof(struct network_interface_info_ioctl_rsp);
6956         }
6957         rtnl_unlock();
6958
6959         /* zero if this is last one */
6960         if (nii_rsp)
6961                 nii_rsp->Next = 0;
6962
6963         if (!nbytes) {
6964                 rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL;
6965                 return -EINVAL;
6966         }
6967
6968         rsp->PersistentFileId = cpu_to_le64(SMB2_NO_FID);
6969         rsp->VolatileFileId = cpu_to_le64(SMB2_NO_FID);
6970         return nbytes;
6971 }
6972
6973 static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn,
6974                 struct validate_negotiate_info_req *neg_req,
6975                 struct validate_negotiate_info_rsp *neg_rsp)
6976 {
6977         int ret = 0;
6978         int dialect;
6979
6980         dialect = ksmbd_lookup_dialect_by_id(neg_req->Dialects,
6981                         neg_req->DialectCount);
6982         if (dialect == BAD_PROT_ID || dialect != conn->dialect) {
6983                 ret = -EINVAL;
6984                 goto err_out;
6985         }
6986
6987         if (strncmp(neg_req->Guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE)) {
6988                 ret = -EINVAL;
6989                 goto err_out;
6990         }
6991
6992         if (le16_to_cpu(neg_req->SecurityMode) != conn->cli_sec_mode) {
6993                 ret = -EINVAL;
6994                 goto err_out;
6995         }
6996
6997         if (le32_to_cpu(neg_req->Capabilities) != conn->cli_cap) {
6998                 ret = -EINVAL;
6999                 goto err_out;
7000         }
7001
7002         neg_rsp->Capabilities = cpu_to_le32(conn->vals->capabilities);
7003         memset(neg_rsp->Guid, 0, SMB2_CLIENT_GUID_SIZE);
7004         neg_rsp->SecurityMode = cpu_to_le16(conn->srv_sec_mode);
7005         neg_rsp->Dialect = cpu_to_le16(conn->dialect);
7006 err_out:
7007         return ret;
7008 }
7009
7010 static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
7011                 struct file_allocated_range_buffer *qar_req,
7012                 struct file_allocated_range_buffer *qar_rsp,
7013                 int in_count, int *out_count)
7014 {
7015         struct ksmbd_file *fp;
7016         loff_t start, length;
7017         int ret = 0;
7018
7019         *out_count = 0;
7020         if (in_count == 0)
7021                 return -EINVAL;
7022
7023         fp = ksmbd_lookup_fd_fast(work, id);
7024         if (!fp)
7025                 return -ENOENT;
7026
7027         start = le64_to_cpu(qar_req->file_offset);
7028         length = le64_to_cpu(qar_req->length);
7029
7030         ret = ksmbd_vfs_fqar_lseek(fp, start, length,
7031                         qar_rsp, in_count, out_count);
7032         if (ret && ret != -E2BIG)
7033                 *out_count = 0;
7034
7035         ksmbd_fd_put(work, fp);
7036         return ret;
7037 }
7038
7039 static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id,
7040                 int out_buf_len, struct smb2_ioctl_req *req,
7041                 struct smb2_ioctl_rsp *rsp)
7042 {
7043         struct ksmbd_rpc_command *rpc_resp;
7044         char *data_buf = (char *)&req->Buffer[0];
7045         int nbytes = 0;
7046
7047         rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf,
7048                         le32_to_cpu(req->InputCount));
7049         if (rpc_resp) {
7050                 if (rpc_resp->flags == KSMBD_RPC_SOME_NOT_MAPPED) {
7051                         /*
7052                          * set STATUS_SOME_NOT_MAPPED response
7053                          * for unknown domain sid.
7054                          */
7055                         rsp->hdr.Status = STATUS_SOME_NOT_MAPPED;
7056                 } else if (rpc_resp->flags == KSMBD_RPC_ENOTIMPLEMENTED) {
7057                         rsp->hdr.Status = STATUS_NOT_SUPPORTED;
7058                         goto out;
7059                 } else if (rpc_resp->flags != KSMBD_RPC_OK) {
7060                         rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7061                         goto out;
7062                 }
7063
7064                 nbytes = rpc_resp->payload_sz;
7065                 if (rpc_resp->payload_sz > out_buf_len) {
7066                         rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
7067                         nbytes = out_buf_len;
7068                 }
7069
7070                 if (!rpc_resp->payload_sz) {
7071                         rsp->hdr.Status =
7072                                 STATUS_UNEXPECTED_IO_ERROR;
7073                         goto out;
7074                 }
7075
7076                 memcpy((char *)rsp->Buffer, rpc_resp->payload, nbytes);
7077         }
7078 out:
7079         kvfree(rpc_resp);
7080         return nbytes;
7081 }
7082
7083 static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
7084                 struct file_sparse *sparse)
7085 {
7086         struct ksmbd_file *fp;
7087         int ret = 0;
7088         __le32 old_fattr;
7089
7090         fp = ksmbd_lookup_fd_fast(work, id);
7091         if (!fp)
7092                 return -ENOENT;
7093
7094         old_fattr = fp->f_ci->m_fattr;
7095         if (sparse->SetSparse)
7096                 fp->f_ci->m_fattr |= ATTR_SPARSE_FILE_LE;
7097         else
7098                 fp->f_ci->m_fattr &= ~ATTR_SPARSE_FILE_LE;
7099
7100         if (fp->f_ci->m_fattr != old_fattr &&
7101             test_share_config_flag(work->tcon->share_conf,
7102                                    KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
7103                 struct xattr_dos_attrib da;
7104
7105                 ret = ksmbd_vfs_get_dos_attrib_xattr(fp->filp->f_path.dentry, &da);
7106                 if (ret <= 0)
7107                         goto out;
7108
7109                 da.attr = le32_to_cpu(fp->f_ci->m_fattr);
7110                 ret = ksmbd_vfs_set_dos_attrib_xattr(fp->filp->f_path.dentry, &da);
7111                 if (ret)
7112                         fp->f_ci->m_fattr = old_fattr;
7113         }
7114
7115 out:
7116         ksmbd_fd_put(work, fp);
7117         return ret;
7118 }
7119
7120 static int fsctl_request_resume_key(struct ksmbd_work *work,
7121                 struct smb2_ioctl_req *req,
7122                 struct resume_key_ioctl_rsp *key_rsp)
7123 {
7124         struct ksmbd_file *fp;
7125
7126         fp = ksmbd_lookup_fd_slow(work,
7127                         le64_to_cpu(req->VolatileFileId),
7128                         le64_to_cpu(req->PersistentFileId));
7129         if (!fp)
7130                 return -ENOENT;
7131
7132         memset(key_rsp, 0, sizeof(*key_rsp));
7133         key_rsp->ResumeKey[0] = req->VolatileFileId;
7134         key_rsp->ResumeKey[1] = req->PersistentFileId;
7135         ksmbd_fd_put(work, fp);
7136
7137         return 0;
7138 }
7139
7140 /**
7141  * smb2_ioctl() - handler for smb2 ioctl command
7142  * @work:       smb work containing ioctl command buffer
7143  *
7144  * Return:      0 on success, otherwise error
7145  */
7146 int smb2_ioctl(struct ksmbd_work *work)
7147 {
7148         struct smb2_ioctl_req *req;
7149         struct smb2_ioctl_rsp *rsp, *rsp_org;
7150         int cnt_code, nbytes = 0;
7151         int out_buf_len;
7152         u64 id = KSMBD_NO_FID;
7153         struct ksmbd_conn *conn = work->conn;
7154         int ret = 0;
7155
7156         rsp_org = work->response_buf;
7157         if (work->next_smb2_rcv_hdr_off) {
7158                 req = REQUEST_BUF_NEXT(work);
7159                 rsp = RESPONSE_BUF_NEXT(work);
7160                 if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
7161                         ksmbd_debug(SMB, "Compound request set FID = %u\n",
7162                                         work->compound_fid);
7163                         id = work->compound_fid;
7164                 }
7165         } else {
7166                 req = work->request_buf;
7167                 rsp = work->response_buf;
7168         }
7169
7170         if (!HAS_FILE_ID(id))
7171                 id = le64_to_cpu(req->VolatileFileId);
7172
7173         if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) {
7174                 rsp->hdr.Status = STATUS_NOT_SUPPORTED;
7175                 goto out;
7176         }
7177
7178         cnt_code = le32_to_cpu(req->CntCode);
7179         out_buf_len = le32_to_cpu(req->MaxOutputResponse);
7180         out_buf_len = min(KSMBD_IPC_MAX_PAYLOAD, out_buf_len);
7181
7182         switch (cnt_code) {
7183         case FSCTL_DFS_GET_REFERRALS:
7184         case FSCTL_DFS_GET_REFERRALS_EX:
7185                 /* Not support DFS yet */
7186                 rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED;
7187                 goto out;
7188         case FSCTL_CREATE_OR_GET_OBJECT_ID:
7189         {
7190                 struct file_object_buf_type1_ioctl_rsp *obj_buf;
7191
7192                 nbytes = sizeof(struct file_object_buf_type1_ioctl_rsp);
7193                 obj_buf = (struct file_object_buf_type1_ioctl_rsp *)
7194                         &rsp->Buffer[0];
7195
7196                 /*
7197                  * TODO: This is dummy implementation to pass smbtorture
7198                  * Need to check correct response later
7199                  */
7200                 memset(obj_buf->ObjectId, 0x0, 16);
7201                 memset(obj_buf->BirthVolumeId, 0x0, 16);
7202                 memset(obj_buf->BirthObjectId, 0x0, 16);
7203                 memset(obj_buf->DomainId, 0x0, 16);
7204
7205                 break;
7206         }
7207         case FSCTL_PIPE_TRANSCEIVE:
7208                 nbytes = fsctl_pipe_transceive(work, id, out_buf_len, req, rsp);
7209                 break;
7210         case FSCTL_VALIDATE_NEGOTIATE_INFO:
7211                 if (conn->dialect < SMB30_PROT_ID) {
7212                         ret = -EOPNOTSUPP;
7213                         goto out;
7214                 }
7215
7216                 ret = fsctl_validate_negotiate_info(conn,
7217                         (struct validate_negotiate_info_req *)&req->Buffer[0],
7218                         (struct validate_negotiate_info_rsp *)&rsp->Buffer[0]);
7219                 if (ret < 0)
7220                         goto out;
7221
7222                 nbytes = sizeof(struct validate_negotiate_info_rsp);
7223                 rsp->PersistentFileId = cpu_to_le64(SMB2_NO_FID);
7224                 rsp->VolatileFileId = cpu_to_le64(SMB2_NO_FID);
7225                 break;
7226         case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
7227                 nbytes = fsctl_query_iface_info_ioctl(conn, req, rsp);
7228                 if (nbytes < 0)
7229                         goto out;
7230                 break;
7231         case FSCTL_REQUEST_RESUME_KEY:
7232                 if (out_buf_len < sizeof(struct resume_key_ioctl_rsp)) {
7233                         ret = -EINVAL;
7234                         goto out;
7235                 }
7236
7237                 ret = fsctl_request_resume_key(work, req,
7238                         (struct resume_key_ioctl_rsp *)&rsp->Buffer[0]);
7239                 if (ret < 0)
7240                         goto out;
7241                 rsp->PersistentFileId = req->PersistentFileId;
7242                 rsp->VolatileFileId = req->VolatileFileId;
7243                 nbytes = sizeof(struct resume_key_ioctl_rsp);
7244                 break;
7245         case FSCTL_COPYCHUNK:
7246         case FSCTL_COPYCHUNK_WRITE:
7247                 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
7248                         ksmbd_debug(SMB,
7249                                 "User does not have write permission\n");
7250                         ret = -EACCES;
7251                         goto out;
7252                 }
7253
7254                 if (out_buf_len < sizeof(struct copychunk_ioctl_rsp)) {
7255                         ret = -EINVAL;
7256                         goto out;
7257                 }
7258
7259                 nbytes = sizeof(struct copychunk_ioctl_rsp);
7260                 fsctl_copychunk(work, req, rsp);
7261                 break;
7262         case FSCTL_SET_SPARSE:
7263                 ret = fsctl_set_sparse(work, id,
7264                         (struct file_sparse *)&req->Buffer[0]);
7265                 if (ret < 0)
7266                         goto out;
7267                 break;
7268         case FSCTL_SET_ZERO_DATA:
7269         {
7270                 struct file_zero_data_information *zero_data;
7271                 struct ksmbd_file *fp;
7272                 loff_t off, len;
7273
7274                 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
7275                         ksmbd_debug(SMB,
7276                                 "User does not have write permission\n");
7277                         ret = -EACCES;
7278                         goto out;
7279                 }
7280
7281                 zero_data =
7282                         (struct file_zero_data_information *)&req->Buffer[0];
7283
7284                 fp = ksmbd_lookup_fd_fast(work, id);
7285                 if (!fp) {
7286                         ret = -ENOENT;
7287                         goto out;
7288                 }
7289
7290                 off = le64_to_cpu(zero_data->FileOffset);
7291                 len = le64_to_cpu(zero_data->BeyondFinalZero) - off;
7292
7293                 ret = ksmbd_vfs_zero_data(work, fp, off, len);
7294                 ksmbd_fd_put(work, fp);
7295                 if (ret < 0)
7296                         goto out;
7297                 break;
7298         }
7299         case FSCTL_QUERY_ALLOCATED_RANGES:
7300                 ret = fsctl_query_allocated_ranges(work, id,
7301                         (struct file_allocated_range_buffer *)&req->Buffer[0],
7302                         (struct file_allocated_range_buffer *)&rsp->Buffer[0],
7303                         out_buf_len /
7304                         sizeof(struct file_allocated_range_buffer), &nbytes);
7305                 if (ret == -E2BIG) {
7306                         rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
7307                 } else if (ret < 0) {
7308                         nbytes = 0;
7309                         goto out;
7310                 }
7311
7312                 nbytes *= sizeof(struct file_allocated_range_buffer);
7313                 break;
7314         case FSCTL_GET_REPARSE_POINT:
7315         {
7316                 struct reparse_data_buffer *reparse_ptr;
7317                 struct ksmbd_file *fp;
7318
7319                 reparse_ptr = (struct reparse_data_buffer *)&rsp->Buffer[0];
7320                 fp = ksmbd_lookup_fd_fast(work, id);
7321                 if (!fp) {
7322                         ksmbd_err("not found fp!!\n");
7323                         ret = -ENOENT;
7324                         goto out;
7325                 }
7326
7327                 reparse_ptr->ReparseTag =
7328                         smb2_get_reparse_tag_special_file(FP_INODE(fp)->i_mode);
7329                 reparse_ptr->ReparseDataLength = 0;
7330                 ksmbd_fd_put(work, fp);
7331                 nbytes = sizeof(struct reparse_data_buffer);
7332                 break;
7333         }
7334         case FSCTL_DUPLICATE_EXTENTS_TO_FILE:
7335         {
7336                 struct ksmbd_file *fp_in, *fp_out = NULL;
7337                 struct duplicate_extents_to_file *dup_ext;
7338                 loff_t src_off, dst_off, length, cloned;
7339
7340                 dup_ext = (struct duplicate_extents_to_file *)&req->Buffer[0];
7341
7342                 fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle,
7343                                 dup_ext->PersistentFileHandle);
7344                 if (!fp_in) {
7345                         ksmbd_err("not found file handle in duplicate extent to file\n");
7346                         ret = -ENOENT;
7347                         goto out;
7348                 }
7349
7350                 fp_out = ksmbd_lookup_fd_fast(work, id);
7351                 if (!fp_out) {
7352                         ksmbd_err("not found fp\n");
7353                         ret = -ENOENT;
7354                         goto dup_ext_out;
7355                 }
7356
7357                 src_off = le64_to_cpu(dup_ext->SourceFileOffset);
7358                 dst_off = le64_to_cpu(dup_ext->TargetFileOffset);
7359                 length = le64_to_cpu(dup_ext->ByteCount);
7360                 cloned = vfs_clone_file_range(fp_in->filp, src_off, fp_out->filp,
7361                                 dst_off, length, 0);
7362                 if (cloned == -EXDEV || cloned == -EOPNOTSUPP) {
7363                         ret = -EOPNOTSUPP;
7364                         goto dup_ext_out;
7365                 } else if (cloned != length) {
7366                         cloned = ksmbd_vfs_copy_file_range(fp_in->filp, src_off,
7367                                         fp_out->filp, dst_off, length);
7368                         if (cloned != length) {
7369                                 if (cloned < 0)
7370                                         ret = cloned;
7371                                 else
7372                                         ret = -EINVAL;
7373                         }
7374                 }
7375
7376 dup_ext_out:
7377                 ksmbd_fd_put(work, fp_in);
7378                 ksmbd_fd_put(work, fp_out);
7379                 if (ret < 0)
7380                         goto out;
7381                 break;
7382         }
7383         default:
7384                 ksmbd_debug(SMB, "not implemented yet ioctl command 0x%x\n",
7385                                 cnt_code);
7386                 ret = -EOPNOTSUPP;
7387                 goto out;
7388         }
7389
7390         rsp->CntCode = cpu_to_le32(cnt_code);
7391         rsp->InputCount = cpu_to_le32(0);
7392         rsp->InputOffset = cpu_to_le32(112);
7393         rsp->OutputOffset = cpu_to_le32(112);
7394         rsp->OutputCount = cpu_to_le32(nbytes);
7395         rsp->StructureSize = cpu_to_le16(49);
7396         rsp->Reserved = cpu_to_le16(0);
7397         rsp->Flags = cpu_to_le32(0);
7398         rsp->Reserved2 = cpu_to_le32(0);
7399         inc_rfc1001_len(rsp_org, 48 + nbytes);
7400
7401         return 0;
7402
7403 out:
7404         if (ret == -EACCES)
7405                 rsp->hdr.Status = STATUS_ACCESS_DENIED;
7406         else if (ret == -ENOENT)
7407                 rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
7408         else if (ret == -EOPNOTSUPP)
7409                 rsp->hdr.Status = STATUS_NOT_SUPPORTED;
7410         else if (ret < 0 || rsp->hdr.Status == 0)
7411                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7412         smb2_set_err_rsp(work);
7413         return 0;
7414 }
7415
7416 /**
7417  * smb20_oplock_break_ack() - handler for smb2.0 oplock break command
7418  * @work:       smb work containing oplock break command buffer
7419  *
7420  * Return:      0
7421  */
7422 static void smb20_oplock_break_ack(struct ksmbd_work *work)
7423 {
7424         struct smb2_oplock_break *req = work->request_buf;
7425         struct smb2_oplock_break *rsp = work->response_buf;
7426         struct ksmbd_file *fp;
7427         struct oplock_info *opinfo = NULL;
7428         __le32 err = 0;
7429         int ret = 0;
7430         u64 volatile_id, persistent_id;
7431         char req_oplevel = 0, rsp_oplevel = 0;
7432         unsigned int oplock_change_type;
7433
7434         volatile_id = le64_to_cpu(req->VolatileFid);
7435         persistent_id = le64_to_cpu(req->PersistentFid);
7436         req_oplevel = req->OplockLevel;
7437         ksmbd_debug(OPLOCK, "v_id %llu, p_id %llu request oplock level %d\n",
7438                     volatile_id, persistent_id, req_oplevel);
7439
7440         fp = ksmbd_lookup_fd_slow(work, volatile_id, persistent_id);
7441         if (!fp) {
7442                 rsp->hdr.Status = STATUS_FILE_CLOSED;
7443                 smb2_set_err_rsp(work);
7444                 return;
7445         }
7446
7447         opinfo = opinfo_get(fp);
7448         if (!opinfo) {
7449                 ksmbd_err("unexpected null oplock_info\n");
7450                 rsp->hdr.Status = STATUS_INVALID_OPLOCK_PROTOCOL;
7451                 smb2_set_err_rsp(work);
7452                 ksmbd_fd_put(work, fp);
7453                 return;
7454         }
7455
7456         if (opinfo->level == SMB2_OPLOCK_LEVEL_NONE) {
7457                 rsp->hdr.Status = STATUS_INVALID_OPLOCK_PROTOCOL;
7458                 goto err_out;
7459         }
7460
7461         if (opinfo->op_state == OPLOCK_STATE_NONE) {
7462                 ksmbd_debug(SMB, "unexpected oplock state 0x%x\n", opinfo->op_state);
7463                 rsp->hdr.Status = STATUS_UNSUCCESSFUL;
7464                 goto err_out;
7465         }
7466
7467         if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
7468              opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
7469             (req_oplevel != SMB2_OPLOCK_LEVEL_II &&
7470              req_oplevel != SMB2_OPLOCK_LEVEL_NONE)) {
7471                 err = STATUS_INVALID_OPLOCK_PROTOCOL;
7472                 oplock_change_type = OPLOCK_WRITE_TO_NONE;
7473         } else if (opinfo->level == SMB2_OPLOCK_LEVEL_II &&
7474                    req_oplevel != SMB2_OPLOCK_LEVEL_NONE) {
7475                 err = STATUS_INVALID_OPLOCK_PROTOCOL;
7476                 oplock_change_type = OPLOCK_READ_TO_NONE;
7477         } else if (req_oplevel == SMB2_OPLOCK_LEVEL_II ||
7478                    req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
7479                 err = STATUS_INVALID_DEVICE_STATE;
7480                 if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
7481                      opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
7482                     req_oplevel == SMB2_OPLOCK_LEVEL_II) {
7483                         oplock_change_type = OPLOCK_WRITE_TO_READ;
7484                 } else if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
7485                             opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
7486                            req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
7487                         oplock_change_type = OPLOCK_WRITE_TO_NONE;
7488                 } else if (opinfo->level == SMB2_OPLOCK_LEVEL_II &&
7489                            req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
7490                         oplock_change_type = OPLOCK_READ_TO_NONE;
7491                 } else {
7492                         oplock_change_type = 0;
7493                 }
7494         } else {
7495                 oplock_change_type = 0;
7496         }
7497
7498         switch (oplock_change_type) {
7499         case OPLOCK_WRITE_TO_READ:
7500                 ret = opinfo_write_to_read(opinfo);
7501                 rsp_oplevel = SMB2_OPLOCK_LEVEL_II;
7502                 break;
7503         case OPLOCK_WRITE_TO_NONE:
7504                 ret = opinfo_write_to_none(opinfo);
7505                 rsp_oplevel = SMB2_OPLOCK_LEVEL_NONE;
7506                 break;
7507         case OPLOCK_READ_TO_NONE:
7508                 ret = opinfo_read_to_none(opinfo);
7509                 rsp_oplevel = SMB2_OPLOCK_LEVEL_NONE;
7510                 break;
7511         default:
7512                 ksmbd_err("unknown oplock change 0x%x -> 0x%x\n",
7513                                 opinfo->level, rsp_oplevel);
7514         }
7515
7516         if (ret < 0) {
7517                 rsp->hdr.Status = err;
7518                 goto err_out;
7519         }
7520
7521         opinfo_put(opinfo);
7522         ksmbd_fd_put(work, fp);
7523         opinfo->op_state = OPLOCK_STATE_NONE;
7524         wake_up_interruptible_all(&opinfo->oplock_q);
7525
7526         rsp->StructureSize = cpu_to_le16(24);
7527         rsp->OplockLevel = rsp_oplevel;
7528         rsp->Reserved = 0;
7529         rsp->Reserved2 = 0;
7530         rsp->VolatileFid = cpu_to_le64(volatile_id);
7531         rsp->PersistentFid = cpu_to_le64(persistent_id);
7532         inc_rfc1001_len(rsp, 24);
7533         return;
7534
7535 err_out:
7536         opinfo->op_state = OPLOCK_STATE_NONE;
7537         wake_up_interruptible_all(&opinfo->oplock_q);
7538
7539         opinfo_put(opinfo);
7540         ksmbd_fd_put(work, fp);
7541         smb2_set_err_rsp(work);
7542 }
7543
7544 static int check_lease_state(struct lease *lease, __le32 req_state)
7545 {
7546         if ((lease->new_state ==
7547              (SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE)) &&
7548             !(req_state & SMB2_LEASE_WRITE_CACHING_LE)) {
7549                 lease->new_state = req_state;
7550                 return 0;
7551         }
7552
7553         if (lease->new_state == req_state)
7554                 return 0;
7555
7556         return 1;
7557 }
7558
7559 /**
7560  * smb21_lease_break_ack() - handler for smb2.1 lease break command
7561  * @work:       smb work containing lease break command buffer
7562  *
7563  * Return:      0
7564  */
7565 static void smb21_lease_break_ack(struct ksmbd_work *work)
7566 {
7567         struct ksmbd_conn *conn = work->conn;
7568         struct smb2_lease_ack *req = work->request_buf;
7569         struct smb2_lease_ack *rsp = work->response_buf;
7570         struct oplock_info *opinfo;
7571         __le32 err = 0;
7572         int ret = 0;
7573         unsigned int lease_change_type;
7574         __le32 lease_state;
7575         struct lease *lease;
7576
7577         ksmbd_debug(OPLOCK, "smb21 lease break, lease state(0x%x)\n",
7578                         le32_to_cpu(req->LeaseState));
7579         opinfo = lookup_lease_in_table(conn, req->LeaseKey);
7580         if (!opinfo) {
7581                 ksmbd_debug(OPLOCK, "file not opened\n");
7582                 smb2_set_err_rsp(work);
7583                 rsp->hdr.Status = STATUS_UNSUCCESSFUL;
7584                 return;
7585         }
7586         lease = opinfo->o_lease;
7587
7588         if (opinfo->op_state == OPLOCK_STATE_NONE) {
7589                 ksmbd_err("unexpected lease break state 0x%x\n",
7590                                 opinfo->op_state);
7591                 rsp->hdr.Status = STATUS_UNSUCCESSFUL;
7592                 goto err_out;
7593         }
7594
7595         if (check_lease_state(lease, req->LeaseState)) {
7596                 rsp->hdr.Status = STATUS_REQUEST_NOT_ACCEPTED;
7597                 ksmbd_debug(OPLOCK,
7598                         "req lease state: 0x%x, expected state: 0x%x\n",
7599                                 req->LeaseState, lease->new_state);
7600                 goto err_out;
7601         }
7602
7603         if (!atomic_read(&opinfo->breaking_cnt)) {
7604                 rsp->hdr.Status = STATUS_UNSUCCESSFUL;
7605                 goto err_out;
7606         }
7607
7608         /* check for bad lease state */
7609         if (req->LeaseState & (~(SMB2_LEASE_READ_CACHING_LE |
7610                                  SMB2_LEASE_HANDLE_CACHING_LE))) {
7611                 err = STATUS_INVALID_OPLOCK_PROTOCOL;
7612                 if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
7613                         lease_change_type = OPLOCK_WRITE_TO_NONE;
7614                 else
7615                         lease_change_type = OPLOCK_READ_TO_NONE;
7616                 ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
7617                         le32_to_cpu(lease->state),
7618                         le32_to_cpu(req->LeaseState));
7619         } else if (lease->state == SMB2_LEASE_READ_CACHING_LE &&
7620                    req->LeaseState != SMB2_LEASE_NONE_LE) {
7621                 err = STATUS_INVALID_OPLOCK_PROTOCOL;
7622                 lease_change_type = OPLOCK_READ_TO_NONE;
7623                 ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
7624                         le32_to_cpu(lease->state),
7625                         le32_to_cpu(req->LeaseState));
7626         } else {
7627                 /* valid lease state changes */
7628                 err = STATUS_INVALID_DEVICE_STATE;
7629                 if (req->LeaseState == SMB2_LEASE_NONE_LE) {
7630                         if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
7631                                 lease_change_type = OPLOCK_WRITE_TO_NONE;
7632                         else
7633                                 lease_change_type = OPLOCK_READ_TO_NONE;
7634                 } else if (req->LeaseState & SMB2_LEASE_READ_CACHING_LE) {
7635                         if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
7636                                 lease_change_type = OPLOCK_WRITE_TO_READ;
7637                         else
7638                                 lease_change_type = OPLOCK_READ_HANDLE_TO_READ;
7639                 } else {
7640                         lease_change_type = 0;
7641                 }
7642         }
7643
7644         switch (lease_change_type) {
7645         case OPLOCK_WRITE_TO_READ:
7646                 ret = opinfo_write_to_read(opinfo);
7647                 break;
7648         case OPLOCK_READ_HANDLE_TO_READ:
7649                 ret = opinfo_read_handle_to_read(opinfo);
7650                 break;
7651         case OPLOCK_WRITE_TO_NONE:
7652                 ret = opinfo_write_to_none(opinfo);
7653                 break;
7654         case OPLOCK_READ_TO_NONE:
7655                 ret = opinfo_read_to_none(opinfo);
7656                 break;
7657         default:
7658                 ksmbd_debug(OPLOCK, "unknown lease change 0x%x -> 0x%x\n",
7659                         le32_to_cpu(lease->state),
7660                         le32_to_cpu(req->LeaseState));
7661         }
7662
7663         lease_state = lease->state;
7664         opinfo->op_state = OPLOCK_STATE_NONE;
7665         wake_up_interruptible_all(&opinfo->oplock_q);
7666         atomic_dec(&opinfo->breaking_cnt);
7667         wake_up_interruptible_all(&opinfo->oplock_brk);
7668         opinfo_put(opinfo);
7669
7670         if (ret < 0) {
7671                 rsp->hdr.Status = err;
7672                 goto err_out;
7673         }
7674
7675         rsp->StructureSize = cpu_to_le16(36);
7676         rsp->Reserved = 0;
7677         rsp->Flags = 0;
7678         memcpy(rsp->LeaseKey, req->LeaseKey, 16);
7679         rsp->LeaseState = lease_state;
7680         rsp->LeaseDuration = 0;
7681         inc_rfc1001_len(rsp, 36);
7682         return;
7683
7684 err_out:
7685         opinfo->op_state = OPLOCK_STATE_NONE;
7686         wake_up_interruptible_all(&opinfo->oplock_q);
7687         atomic_dec(&opinfo->breaking_cnt);
7688         wake_up_interruptible_all(&opinfo->oplock_brk);
7689
7690         opinfo_put(opinfo);
7691         smb2_set_err_rsp(work);
7692 }
7693
7694 /**
7695  * smb2_oplock_break() - dispatcher for smb2.0 and 2.1 oplock/lease break
7696  * @work:       smb work containing oplock/lease break command buffer
7697  *
7698  * Return:      0
7699  */
7700 int smb2_oplock_break(struct ksmbd_work *work)
7701 {
7702         struct smb2_oplock_break *req = work->request_buf;
7703         struct smb2_oplock_break *rsp = work->response_buf;
7704
7705         switch (le16_to_cpu(req->StructureSize)) {
7706         case OP_BREAK_STRUCT_SIZE_20:
7707                 smb20_oplock_break_ack(work);
7708                 break;
7709         case OP_BREAK_STRUCT_SIZE_21:
7710                 smb21_lease_break_ack(work);
7711                 break;
7712         default:
7713                 ksmbd_debug(OPLOCK, "invalid break cmd %d\n",
7714                         le16_to_cpu(req->StructureSize));
7715                 rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7716                 smb2_set_err_rsp(work);
7717         }
7718
7719         return 0;
7720 }
7721
7722 /**
7723  * smb2_notify() - handler for smb2 notify request
7724  * @work:   smb work containing notify command buffer
7725  *
7726  * Return:      0
7727  */
7728 int smb2_notify(struct ksmbd_work *work)
7729 {
7730         struct smb2_notify_req *req;
7731         struct smb2_notify_rsp *rsp;
7732
7733         WORK_BUFFERS(work, req, rsp);
7734
7735         if (work->next_smb2_rcv_hdr_off && req->hdr.NextCommand) {
7736                 rsp->hdr.Status = STATUS_INTERNAL_ERROR;
7737                 smb2_set_err_rsp(work);
7738                 return 0;
7739         }
7740
7741         smb2_set_err_rsp(work);
7742         rsp->hdr.Status = STATUS_NOT_IMPLEMENTED;
7743         return 0;
7744 }
7745
7746 /**
7747  * smb2_is_sign_req() - handler for checking packet signing status
7748  * @work:       smb work containing notify command buffer
7749  * @command:    SMB2 command id
7750  *
7751  * Return:      true if packed is signed, false otherwise
7752  */
7753 bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command)
7754 {
7755         struct smb2_hdr *rcv_hdr2 = work->request_buf;
7756
7757         if ((rcv_hdr2->Flags & SMB2_FLAGS_SIGNED) &&
7758             command != SMB2_NEGOTIATE_HE &&
7759             command != SMB2_SESSION_SETUP_HE &&
7760             command != SMB2_OPLOCK_BREAK_HE)
7761                 return true;
7762
7763         return false;
7764 }
7765
7766 /**
7767  * smb2_check_sign_req() - handler for req packet sign processing
7768  * @work:   smb work containing notify command buffer
7769  *
7770  * Return:      1 on success, 0 otherwise
7771  */
7772 int smb2_check_sign_req(struct ksmbd_work *work)
7773 {
7774         struct smb2_hdr *hdr, *hdr_org;
7775         char signature_req[SMB2_SIGNATURE_SIZE];
7776         char signature[SMB2_HMACSHA256_SIZE];
7777         struct kvec iov[1];
7778         size_t len;
7779
7780         hdr_org = hdr = work->request_buf;
7781         if (work->next_smb2_rcv_hdr_off)
7782                 hdr = REQUEST_BUF_NEXT(work);
7783
7784         if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off)
7785                 len = be32_to_cpu(hdr_org->smb2_buf_length);
7786         else if (hdr->NextCommand)
7787                 len = le32_to_cpu(hdr->NextCommand);
7788         else
7789                 len = be32_to_cpu(hdr_org->smb2_buf_length) -
7790                         work->next_smb2_rcv_hdr_off;
7791
7792         memcpy(signature_req, hdr->Signature, SMB2_SIGNATURE_SIZE);
7793         memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
7794
7795         iov[0].iov_base = (char *)&hdr->ProtocolId;
7796         iov[0].iov_len = len;
7797
7798         if (ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1,
7799                                 signature))
7800                 return 0;
7801
7802         if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
7803                 ksmbd_err("bad smb2 signature\n");
7804                 return 0;
7805         }
7806
7807         return 1;
7808 }
7809
7810 /**
7811  * smb2_set_sign_rsp() - handler for rsp packet sign processing
7812  * @work:   smb work containing notify command buffer
7813  *
7814  */
7815 void smb2_set_sign_rsp(struct ksmbd_work *work)
7816 {
7817         struct smb2_hdr *hdr, *hdr_org;
7818         struct smb2_hdr *req_hdr;
7819         char signature[SMB2_HMACSHA256_SIZE];
7820         struct kvec iov[2];
7821         size_t len;
7822         int n_vec = 1;
7823
7824         hdr_org = hdr = work->response_buf;
7825         if (work->next_smb2_rsp_hdr_off)
7826                 hdr = RESPONSE_BUF_NEXT(work);
7827
7828         req_hdr = REQUEST_BUF_NEXT(work);
7829
7830         if (!work->next_smb2_rsp_hdr_off) {
7831                 len = get_rfc1002_len(hdr_org);
7832                 if (req_hdr->NextCommand)
7833                         len = ALIGN(len, 8);
7834         } else {
7835                 len = get_rfc1002_len(hdr_org) - work->next_smb2_rsp_hdr_off;
7836                 len = ALIGN(len, 8);
7837         }
7838
7839         if (req_hdr->NextCommand)
7840                 hdr->NextCommand = cpu_to_le32(len);
7841
7842         hdr->Flags |= SMB2_FLAGS_SIGNED;
7843         memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
7844
7845         iov[0].iov_base = (char *)&hdr->ProtocolId;
7846         iov[0].iov_len = len;
7847
7848         if (work->aux_payload_sz) {
7849                 iov[0].iov_len -= work->aux_payload_sz;
7850
7851                 iov[1].iov_base = work->aux_payload_buf;
7852                 iov[1].iov_len = work->aux_payload_sz;
7853                 n_vec++;
7854         }
7855
7856         if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
7857                                  signature))
7858                 memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
7859 }
7860
7861 /**
7862  * smb3_check_sign_req() - handler for req packet sign processing
7863  * @work:   smb work containing notify command buffer
7864  *
7865  * Return:      1 on success, 0 otherwise
7866  */
7867 int smb3_check_sign_req(struct ksmbd_work *work)
7868 {
7869         struct ksmbd_conn *conn;
7870         char *signing_key;
7871         struct smb2_hdr *hdr, *hdr_org;
7872         struct channel *chann;
7873         char signature_req[SMB2_SIGNATURE_SIZE];
7874         char signature[SMB2_CMACAES_SIZE];
7875         struct kvec iov[1];
7876         size_t len;
7877
7878         hdr_org = hdr = work->request_buf;
7879         if (work->next_smb2_rcv_hdr_off)
7880                 hdr = REQUEST_BUF_NEXT(work);
7881
7882         if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off)
7883                 len = be32_to_cpu(hdr_org->smb2_buf_length);
7884         else if (hdr->NextCommand)
7885                 len = le32_to_cpu(hdr->NextCommand);
7886         else
7887                 len = be32_to_cpu(hdr_org->smb2_buf_length) -
7888                         work->next_smb2_rcv_hdr_off;
7889
7890         if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
7891                 signing_key = work->sess->smb3signingkey;
7892                 conn = work->sess->conn;
7893         } else {
7894                 chann = lookup_chann_list(work->sess);
7895                 if (!chann)
7896                         return 0;
7897                 signing_key = chann->smb3signingkey;
7898                 conn = chann->conn;
7899         }
7900
7901         if (!signing_key) {
7902                 ksmbd_err("SMB3 signing key is not generated\n");
7903                 return 0;
7904         }
7905
7906         memcpy(signature_req, hdr->Signature, SMB2_SIGNATURE_SIZE);
7907         memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
7908         iov[0].iov_base = (char *)&hdr->ProtocolId;
7909         iov[0].iov_len = len;
7910
7911         if (ksmbd_sign_smb3_pdu(conn, signing_key, iov, 1, signature))
7912                 return 0;
7913
7914         if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
7915                 ksmbd_err("bad smb2 signature\n");
7916                 return 0;
7917         }
7918
7919         return 1;
7920 }
7921
7922 /**
7923  * smb3_set_sign_rsp() - handler for rsp packet sign processing
7924  * @work:   smb work containing notify command buffer
7925  *
7926  */
7927 void smb3_set_sign_rsp(struct ksmbd_work *work)
7928 {
7929         struct ksmbd_conn *conn;
7930         struct smb2_hdr *req_hdr;
7931         struct smb2_hdr *hdr, *hdr_org;
7932         struct channel *chann;
7933         char signature[SMB2_CMACAES_SIZE];
7934         struct kvec iov[2];
7935         int n_vec = 1;
7936         size_t len;
7937         char *signing_key;
7938
7939         hdr_org = hdr = work->response_buf;
7940         if (work->next_smb2_rsp_hdr_off)
7941                 hdr = RESPONSE_BUF_NEXT(work);
7942
7943         req_hdr = REQUEST_BUF_NEXT(work);
7944
7945         if (!work->next_smb2_rsp_hdr_off) {
7946                 len = get_rfc1002_len(hdr_org);
7947                 if (req_hdr->NextCommand)
7948                         len = ALIGN(len, 8);
7949         } else {
7950                 len = get_rfc1002_len(hdr_org) - work->next_smb2_rsp_hdr_off;
7951                 len = ALIGN(len, 8);
7952         }
7953
7954         if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
7955                 signing_key = work->sess->smb3signingkey;
7956                 conn = work->sess->conn;
7957         } else {
7958                 chann = lookup_chann_list(work->sess);
7959                 if (!chann)
7960                         return;
7961                 signing_key = chann->smb3signingkey;
7962                 conn = chann->conn;
7963         }
7964
7965         if (!signing_key)
7966                 return;
7967
7968         if (req_hdr->NextCommand)
7969                 hdr->NextCommand = cpu_to_le32(len);
7970
7971         hdr->Flags |= SMB2_FLAGS_SIGNED;
7972         memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
7973         iov[0].iov_base = (char *)&hdr->ProtocolId;
7974         iov[0].iov_len = len;
7975         if (work->aux_payload_sz) {
7976                 iov[0].iov_len -= work->aux_payload_sz;
7977                 iov[1].iov_base = work->aux_payload_buf;
7978                 iov[1].iov_len = work->aux_payload_sz;
7979                 n_vec++;
7980         }
7981
7982         if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature))
7983                 memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
7984 }
7985
7986 /**
7987  * smb3_preauth_hash_rsp() - handler for computing preauth hash on response
7988  * @work:   smb work containing response buffer
7989  *
7990  */
7991 void smb3_preauth_hash_rsp(struct ksmbd_work *work)
7992 {
7993         struct ksmbd_conn *conn = work->conn;
7994         struct ksmbd_session *sess = work->sess;
7995         struct smb2_hdr *req, *rsp;
7996
7997         if (conn->dialect != SMB311_PROT_ID)
7998                 return;
7999
8000         WORK_BUFFERS(work, req, rsp);
8001
8002         if (le16_to_cpu(req->Command) == SMB2_NEGOTIATE_HE)
8003                 ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp,
8004                         conn->preauth_info->Preauth_HashValue);
8005
8006         if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
8007             sess && sess->state == SMB2_SESSION_IN_PROGRESS) {
8008                 __u8 *hash_value;
8009
8010                 hash_value = sess->Preauth_HashValue;
8011                 ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp,
8012                                 hash_value);
8013         }
8014 }
8015
8016 static void fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, char *old_buf,
8017                 __le16 cipher_type)
8018 {
8019         struct smb2_hdr *hdr = (struct smb2_hdr *)old_buf;
8020         unsigned int orig_len = get_rfc1002_len(old_buf);
8021
8022         memset(tr_hdr, 0, sizeof(struct smb2_transform_hdr));
8023         tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
8024         tr_hdr->OriginalMessageSize = cpu_to_le32(orig_len);
8025         tr_hdr->Flags = cpu_to_le16(0x01);
8026         if (cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
8027             cipher_type == SMB2_ENCRYPTION_AES256_GCM)
8028                 get_random_bytes(&tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
8029         else
8030                 get_random_bytes(&tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
8031         memcpy(&tr_hdr->SessionId, &hdr->SessionId, 8);
8032         inc_rfc1001_len(tr_hdr, sizeof(struct smb2_transform_hdr) - 4);
8033         inc_rfc1001_len(tr_hdr, orig_len);
8034 }
8035
8036 int smb3_encrypt_resp(struct ksmbd_work *work)
8037 {
8038         char *buf = work->response_buf;
8039         struct smb2_transform_hdr *tr_hdr;
8040         struct kvec iov[3];
8041         int rc = -ENOMEM;
8042         int buf_size = 0, rq_nvec = 2 + (work->aux_payload_sz ? 1 : 0);
8043
8044         if (ARRAY_SIZE(iov) < rq_nvec)
8045                 return -ENOMEM;
8046
8047         tr_hdr = kzalloc(sizeof(struct smb2_transform_hdr), GFP_KERNEL);
8048         if (!tr_hdr)
8049                 return rc;
8050
8051         /* fill transform header */
8052         fill_transform_hdr(tr_hdr, buf, work->conn->cipher_type);
8053
8054         iov[0].iov_base = tr_hdr;
8055         iov[0].iov_len = sizeof(struct smb2_transform_hdr);
8056         buf_size += iov[0].iov_len - 4;
8057
8058         iov[1].iov_base = buf + 4;
8059         iov[1].iov_len = get_rfc1002_len(buf);
8060         if (work->aux_payload_sz) {
8061                 iov[1].iov_len = work->resp_hdr_sz - 4;
8062
8063                 iov[2].iov_base = work->aux_payload_buf;
8064                 iov[2].iov_len = work->aux_payload_sz;
8065                 buf_size += iov[2].iov_len;
8066         }
8067         buf_size += iov[1].iov_len;
8068         work->resp_hdr_sz = iov[1].iov_len;
8069
8070         rc = ksmbd_crypt_message(work->conn, iov, rq_nvec, 1);
8071         if (rc)
8072                 return rc;
8073
8074         memmove(buf, iov[1].iov_base, iov[1].iov_len);
8075         tr_hdr->smb2_buf_length = cpu_to_be32(buf_size);
8076         work->tr_buf = tr_hdr;
8077
8078         return rc;
8079 }
8080
8081 int smb3_is_transform_hdr(void *buf)
8082 {
8083         struct smb2_transform_hdr *trhdr = buf;
8084
8085         return trhdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM;
8086 }
8087
8088 int smb3_decrypt_req(struct ksmbd_work *work)
8089 {
8090         struct ksmbd_conn *conn = work->conn;
8091         struct ksmbd_session *sess;
8092         char *buf = work->request_buf;
8093         struct smb2_hdr *hdr;
8094         unsigned int pdu_length = get_rfc1002_len(buf);
8095         struct kvec iov[2];
8096         unsigned int buf_data_size = pdu_length + 4 -
8097                 sizeof(struct smb2_transform_hdr);
8098         struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf;
8099         unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
8100         int rc = 0;
8101
8102         sess = ksmbd_session_lookup(conn, le64_to_cpu(tr_hdr->SessionId));
8103         if (!sess) {
8104                 ksmbd_err("invalid session id(%llx) in transform header\n",
8105                         le64_to_cpu(tr_hdr->SessionId));
8106                 return -ECONNABORTED;
8107         }
8108
8109         if (pdu_length + 4 < sizeof(struct smb2_transform_hdr) +
8110                         sizeof(struct smb2_hdr)) {
8111                 ksmbd_err("Transform message is too small (%u)\n",
8112                                 pdu_length);
8113                 return -ECONNABORTED;
8114         }
8115
8116         if (pdu_length + 4 < orig_len + sizeof(struct smb2_transform_hdr)) {
8117                 ksmbd_err("Transform message is broken\n");
8118                 return -ECONNABORTED;
8119         }
8120
8121         iov[0].iov_base = buf;
8122         iov[0].iov_len = sizeof(struct smb2_transform_hdr);
8123         iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr);
8124         iov[1].iov_len = buf_data_size;
8125         rc = ksmbd_crypt_message(conn, iov, 2, 0);
8126         if (rc)
8127                 return rc;
8128
8129         memmove(buf + 4, iov[1].iov_base, buf_data_size);
8130         hdr = (struct smb2_hdr *)buf;
8131         hdr->smb2_buf_length = cpu_to_be32(buf_data_size);
8132
8133         return rc;
8134 }
8135
8136 bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
8137 {
8138         struct ksmbd_conn *conn = work->conn;
8139         struct smb2_hdr *rsp = work->response_buf;
8140
8141         if (conn->dialect < SMB30_PROT_ID)
8142                 return false;
8143
8144         if (work->next_smb2_rcv_hdr_off)
8145                 rsp = RESPONSE_BUF_NEXT(work);
8146
8147         if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
8148             rsp->Status == STATUS_SUCCESS)
8149                 return true;
8150         return false;
8151 }