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