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