smbd: Remove the offset argument from ReadDirName()
[samba.git] / source3 / smbd / smb1_trans2.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2007
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    Copyright (C) Volker Lendecke                2005-2007
7    Copyright (C) Steve French                   2005
8    Copyright (C) James Peach                    2006-2007
9
10    Extensively modified by Andrew Tridgell, 1995
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "includes.h"
27 #include "ntioctl.h"
28 #include "system/filesys.h"
29 #include "lib/util/time_basic.h"
30 #include "version.h"
31 #include "smbd/smbd.h"
32 #include "smbd/globals.h"
33 #include "../libcli/auth/libcli_auth.h"
34 #include "../librpc/gen_ndr/xattr.h"
35 #include "../librpc/gen_ndr/ndr_security.h"
36 #include "libcli/security/security.h"
37 #include "trans2.h"
38 #include "auth.h"
39 #include "smbprofile.h"
40 #include "rpc_server/srv_pipe_hnd.h"
41 #include "printing.h"
42 #include "lib/util_ea.h"
43 #include "lib/readdir_attr.h"
44 #include "messages.h"
45 #include "libcli/smb/smb2_posix.h"
46 #include "lib/util/string_wrappers.h"
47 #include "source3/lib/substitute.h"
48 #include "source3/lib/adouble.h"
49
50 #define DIR_ENTRY_SAFETY_MARGIN 4096
51
52 /****************************************************************************
53   Send the required number of replies back.
54   We assume all fields other than the data fields are
55   set correctly for the type of call.
56   HACK ! Always assumes smb_setup field is zero.
57 ****************************************************************************/
58
59 static void send_trans2_replies(connection_struct *conn,
60                                 struct smb_request *req,
61                                 NTSTATUS status,
62                                 const char *params,
63                                 int paramsize,
64                                 const char *pdata,
65                                 int datasize,
66                                 int max_data_bytes)
67 {
68         /* As we are using a protocol > LANMAN1 then the max_send
69          variable must have been set in the sessetupX call.
70          This takes precedence over the max_xmit field in the
71          global struct. These different max_xmit variables should
72          be merged as this is now too confusing */
73
74         int data_to_send = datasize;
75         int params_to_send = paramsize;
76         int useable_space;
77         const char *pp = params;
78         const char *pd = pdata;
79         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
80         int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
81         int data_alignment_offset = 0;
82         bool overflow = False;
83         struct smbXsrv_connection *xconn = req->xconn;
84         int max_send = xconn->smb1.sessions.max_send;
85
86         /* Modify the data_to_send and datasize and set the error if
87            we're trying to send more than max_data_bytes. We still send
88            the part of the packet(s) that fit. Strange, but needed
89            for OS/2. */
90
91         if (max_data_bytes > 0 && datasize > max_data_bytes) {
92                 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
93                         max_data_bytes, datasize ));
94                 datasize = data_to_send = max_data_bytes;
95                 overflow = True;
96         }
97
98         /* If there genuinely are no parameters or data to send just send the empty packet */
99
100         if(params_to_send == 0 && data_to_send == 0) {
101                 reply_smb1_outbuf(req, 10, 0);
102                 if (NT_STATUS_V(status)) {
103                         uint8_t eclass;
104                         uint32_t ecode;
105                         ntstatus_to_dos(status, &eclass, &ecode);
106                         error_packet_set((char *)req->outbuf,
107                                         eclass, ecode, status,
108                                         __LINE__,__FILE__);
109                 }
110                 show_msg((char *)req->outbuf);
111                 if (!smb1_srv_send(xconn,
112                                    (char *)req->outbuf,
113                                    true,
114                                    req->seqnum + 1,
115                                    IS_CONN_ENCRYPTED(conn))) {
116                         exit_server_cleanly("send_trans2_replies: smb1_srv_send failed.");
117                 }
118                 TALLOC_FREE(req->outbuf);
119                 return;
120         }
121
122         /* When sending params and data ensure that both are nicely aligned */
123         /* Only do this alignment when there is also data to send - else
124                 can cause NT redirector problems. */
125
126         if (((params_to_send % 4) != 0) && (data_to_send != 0))
127                 data_alignment_offset = 4 - (params_to_send % 4);
128
129         /* Space is bufsize minus Netbios over TCP header minus SMB header */
130         /* The alignment_offset is to align the param bytes on an even byte
131                 boundary. NT 4.0 Beta needs this to work correctly. */
132
133         useable_space = max_send - (smb_size
134                                     + 2 * 10 /* wct */
135                                     + alignment_offset
136                                     + data_alignment_offset);
137
138         if (useable_space < 0) {
139                 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
140                           "= %d!!!", useable_space));
141                 exit_server_cleanly("send_trans2_replies: Not enough space");
142         }
143
144         while (params_to_send || data_to_send) {
145                 /* Calculate whether we will totally or partially fill this packet */
146
147                 total_sent_thistime = params_to_send + data_to_send;
148
149                 /* We can never send more than useable_space */
150                 /*
151                  * Note that 'useable_space' does not include the alignment offsets,
152                  * but we must include the alignment offsets in the calculation of
153                  * the length of the data we send over the wire, as the alignment offsets
154                  * are sent here. Fix from Marc_Jacobsen@hp.com.
155                  */
156
157                 total_sent_thistime = MIN(total_sent_thistime, useable_space);
158
159                 reply_smb1_outbuf(req, 10, total_sent_thistime + alignment_offset
160                              + data_alignment_offset);
161
162                 /* Set total params and data to be sent */
163                 SSVAL(req->outbuf,smb_tprcnt,paramsize);
164                 SSVAL(req->outbuf,smb_tdrcnt,datasize);
165
166                 /* Calculate how many parameters and data we can fit into
167                  * this packet. Parameters get precedence
168                  */
169
170                 params_sent_thistime = MIN(params_to_send,useable_space);
171                 data_sent_thistime = useable_space - params_sent_thistime;
172                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
173
174                 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
175
176                 /* smb_proff is the offset from the start of the SMB header to the
177                         parameter bytes, however the first 4 bytes of outbuf are
178                         the Netbios over TCP header. Thus use smb_base() to subtract
179                         them from the calculation */
180
181                 SSVAL(req->outbuf,smb_proff,
182                       ((smb_buf(req->outbuf)+alignment_offset)
183                        - smb_base(req->outbuf)));
184
185                 if(params_sent_thistime == 0)
186                         SSVAL(req->outbuf,smb_prdisp,0);
187                 else
188                         /* Absolute displacement of param bytes sent in this packet */
189                         SSVAL(req->outbuf,smb_prdisp,pp - params);
190
191                 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
192                 if(data_sent_thistime == 0) {
193                         SSVAL(req->outbuf,smb_droff,0);
194                         SSVAL(req->outbuf,smb_drdisp, 0);
195                 } else {
196                         /* The offset of the data bytes is the offset of the
197                                 parameter bytes plus the number of parameters being sent this time */
198                         SSVAL(req->outbuf, smb_droff,
199                               ((smb_buf(req->outbuf)+alignment_offset)
200                                - smb_base(req->outbuf))
201                               + params_sent_thistime + data_alignment_offset);
202                         SSVAL(req->outbuf,smb_drdisp, pd - pdata);
203                 }
204
205                 /* Initialize the padding for alignment */
206
207                 if (alignment_offset != 0) {
208                         memset(smb_buf(req->outbuf), 0, alignment_offset);
209                 }
210
211                 /* Copy the param bytes into the packet */
212
213                 if(params_sent_thistime) {
214                         memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
215                                params_sent_thistime);
216                 }
217
218                 /* Copy in the data bytes */
219                 if(data_sent_thistime) {
220                         if (data_alignment_offset != 0) {
221                                 memset((smb_buf(req->outbuf)+alignment_offset+
222                                         params_sent_thistime), 0,
223                                        data_alignment_offset);
224                         }
225                         memcpy(smb_buf(req->outbuf)+alignment_offset
226                                +params_sent_thistime+data_alignment_offset,
227                                pd,data_sent_thistime);
228                 }
229
230                 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
231                         params_sent_thistime, data_sent_thistime, useable_space));
232                 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
233                         params_to_send, data_to_send, paramsize, datasize));
234
235                 if (overflow) {
236                         error_packet_set((char *)req->outbuf,
237                                          ERRDOS,ERRbufferoverflow,
238                                          STATUS_BUFFER_OVERFLOW,
239                                          __LINE__,__FILE__);
240                 } else if (NT_STATUS_V(status)) {
241                         uint8_t eclass;
242                         uint32_t ecode;
243                         ntstatus_to_dos(status, &eclass, &ecode);
244                         error_packet_set((char *)req->outbuf,
245                                         eclass, ecode, status,
246                                         __LINE__,__FILE__);
247                 }
248
249                 /* Send the packet */
250                 show_msg((char *)req->outbuf);
251                 if (!smb1_srv_send(xconn,
252                                    (char *)req->outbuf,
253                                    true,
254                                    req->seqnum + 1,
255                                    IS_CONN_ENCRYPTED(conn))) {
256                         exit_server_cleanly("send_trans2_replies: smb1_srv_send failed.");
257                 }
258
259                 TALLOC_FREE(req->outbuf);
260
261                 pp += params_sent_thistime;
262                 pd += data_sent_thistime;
263
264                 params_to_send -= params_sent_thistime;
265                 data_to_send -= data_sent_thistime;
266
267                 /* Sanity check */
268                 if(params_to_send < 0 || data_to_send < 0) {
269                         DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
270                                 params_to_send, data_to_send));
271                         return;
272                 }
273         }
274
275         return;
276 }
277
278 /****************************************************************************
279  Deal with SMB_SET_POSIX_LOCK.
280 ****************************************************************************/
281
282 static void smb_set_posix_lock_done(struct tevent_req *subreq);
283
284 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
285                                    struct smb_request *req,
286                                    const char *pdata,
287                                    int total_data,
288                                    files_struct *fsp)
289 {
290         struct tevent_req *subreq = NULL;
291         struct smbd_lock_element *lck = NULL;
292         uint64_t count;
293         uint64_t offset;
294         uint64_t smblctx;
295         bool blocking_lock = False;
296         enum brl_type lock_type;
297
298         NTSTATUS status = NT_STATUS_OK;
299
300         if (!CAN_WRITE(conn)) {
301                 return NT_STATUS_DOS(ERRSRV, ERRaccess);
302         }
303
304         if (fsp == NULL ||
305             fsp->fsp_flags.is_pathref ||
306             fsp_get_io_fd(fsp) == -1)
307         {
308                 return NT_STATUS_INVALID_HANDLE;
309         }
310
311         if (total_data != POSIX_LOCK_DATA_SIZE) {
312                 return NT_STATUS_INVALID_PARAMETER;
313         }
314
315         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
316                 case POSIX_LOCK_TYPE_READ:
317                         lock_type = READ_LOCK;
318                         break;
319                 case POSIX_LOCK_TYPE_WRITE:
320                         /* Return the right POSIX-mappable error code for files opened read-only. */
321                         if (!fsp->fsp_flags.can_write) {
322                                 return NT_STATUS_INVALID_HANDLE;
323                         }
324                         lock_type = WRITE_LOCK;
325                         break;
326                 case POSIX_LOCK_TYPE_UNLOCK:
327                         lock_type = UNLOCK_LOCK;
328                         break;
329                 default:
330                         return NT_STATUS_INVALID_PARAMETER;
331         }
332
333         switch (SVAL(pdata, POSIX_LOCK_FLAGS_OFFSET)) {
334         case POSIX_LOCK_FLAG_NOWAIT:
335                 blocking_lock = false;
336                 break;
337         case POSIX_LOCK_FLAG_WAIT:
338                 blocking_lock = true;
339                 break;
340         default:
341                 return NT_STATUS_INVALID_PARAMETER;
342         }
343
344         if (!lp_blocking_locks(SNUM(conn))) {
345                 blocking_lock = False;
346         }
347
348         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
349         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
350                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
351         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
352                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
353
354         DBG_DEBUG("file %s, lock_type = %u, smblctx = %"PRIu64", "
355                   "count = %"PRIu64", offset = %"PRIu64"\n",
356                   fsp_str_dbg(fsp),
357                   (unsigned int)lock_type,
358                   smblctx,
359                   count,
360                   offset);
361
362         if (lock_type == UNLOCK_LOCK) {
363                 struct smbd_lock_element l = {
364                         .req_guid = smbd_request_guid(req, 0),
365                         .smblctx = smblctx,
366                         .brltype = UNLOCK_LOCK,
367                         .lock_flav = POSIX_LOCK,
368                         .offset = offset,
369                         .count = count,
370                 };
371                 status = smbd_do_unlocking(req, fsp, 1, &l);
372                 return status;
373         }
374
375         lck = talloc(req, struct smbd_lock_element);
376         if (lck == NULL) {
377                 return NT_STATUS_NO_MEMORY;
378         }
379
380         *lck = (struct smbd_lock_element) {
381                 .req_guid = smbd_request_guid(req, 0),
382                 .smblctx = smblctx,
383                 .brltype = lock_type,
384                 .lock_flav = POSIX_LOCK,
385                 .count = count,
386                 .offset = offset,
387         };
388
389         subreq = smbd_smb1_do_locks_send(
390                 fsp,
391                 req->sconn->ev_ctx,
392                 &req,
393                 fsp,
394                 blocking_lock ? UINT32_MAX : 0,
395                 true,           /* large_offset */
396                 1,
397                 lck);
398         if (subreq == NULL) {
399                 TALLOC_FREE(lck);
400                 return NT_STATUS_NO_MEMORY;
401         }
402         tevent_req_set_callback(subreq, smb_set_posix_lock_done, req);
403         return NT_STATUS_EVENT_PENDING;
404 }
405
406 static void smb_set_posix_lock_done(struct tevent_req *subreq)
407 {
408         struct smb_request *req = NULL;
409         NTSTATUS status;
410         bool ok;
411
412         ok = smbd_smb1_do_locks_extract_smbreq(subreq, talloc_tos(), &req);
413         SMB_ASSERT(ok);
414
415         status = smbd_smb1_do_locks_recv(subreq);
416         TALLOC_FREE(subreq);
417
418         if (NT_STATUS_IS_OK(status)) {
419                 char params[2] = {0};
420                 /* Fake up max_data_bytes here - we know it fits. */
421                 send_trans2_replies(
422                         req->conn,
423                         req,
424                         NT_STATUS_OK,
425                         params,
426                         2,
427                         NULL,
428                         0,
429                         0xffff);
430         } else {
431                 reply_nterror(req, status);
432                 ok = smb1_srv_send(req->xconn,
433                                    (char *)req->outbuf,
434                                    true,
435                                    req->seqnum + 1,
436                                    IS_CONN_ENCRYPTED(req->conn));
437                 if (!ok) {
438                         exit_server_cleanly("smb_set_posix_lock_done: "
439                                             "smb1_srv_send failed.");
440                 }
441         }
442
443         TALLOC_FREE(req);
444         return;
445 }
446
447 /****************************************************************************
448  Read a list of EA names from an incoming data buffer. Create an ea_list with them.
449 ****************************************************************************/
450
451 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
452 {
453         struct ea_list *ea_list_head = NULL;
454         size_t converted_size, offset = 0;
455
456         while (offset + 2 < data_size) {
457                 struct ea_list *eal = talloc_zero(ctx, struct ea_list);
458                 unsigned int namelen = CVAL(pdata,offset);
459
460                 offset++; /* Go past the namelen byte. */
461
462                 /* integer wrap paranioa. */
463                 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
464                                 (offset > data_size) || (namelen > data_size) ||
465                                 (offset + namelen >= data_size)) {
466                         break;
467                 }
468                 /* Ensure the name is null terminated. */
469                 if (pdata[offset + namelen] != '\0') {
470                         return NULL;
471                 }
472                 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
473                                        &converted_size)) {
474                         DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
475                                  "failed: %s", strerror(errno)));
476                 }
477                 if (!eal->ea.name) {
478                         return NULL;
479                 }
480
481                 offset += (namelen + 1); /* Go past the name + terminating zero. */
482                 DLIST_ADD_END(ea_list_head, eal);
483                 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
484         }
485
486         return ea_list_head;
487 }
488
489 /****************************************************************************
490  Reply to a TRANSACT2_OPEN.
491 ****************************************************************************/
492
493 static void call_trans2open(connection_struct *conn,
494                             struct smb_request *req,
495                             char **pparams, int total_params,
496                             char **ppdata, int total_data,
497                             unsigned int max_data_bytes)
498 {
499         struct smb_filename *smb_fname = NULL;
500         char *params = *pparams;
501         char *pdata = *ppdata;
502         int deny_mode;
503         int32_t open_attr;
504         bool oplock_request;
505 #if 0
506         bool return_additional_info;
507         int16 open_sattr;
508         time_t open_time;
509 #endif
510         int open_ofun;
511         uint32_t open_size;
512         char *pname;
513         char *fname = NULL;
514         off_t size=0;
515         int fattr=0,mtime=0;
516         SMB_INO_T inode = 0;
517         int smb_action = 0;
518         struct files_struct *dirfsp = NULL;
519         files_struct *fsp;
520         struct ea_list *ea_list = NULL;
521         uint16_t flags = 0;
522         NTSTATUS status;
523         uint32_t access_mask;
524         uint32_t share_mode;
525         uint32_t create_disposition;
526         uint32_t create_options = 0;
527         uint32_t private_flags = 0;
528         NTTIME twrp = 0;
529         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
530         TALLOC_CTX *ctx = talloc_tos();
531
532         /*
533          * Ensure we have enough parameters to perform the operation.
534          */
535
536         if (total_params < 29) {
537                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
538                 goto out;
539         }
540
541         flags = SVAL(params, 0);
542         deny_mode = SVAL(params, 2);
543         open_attr = SVAL(params,6);
544         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
545         if (oplock_request) {
546                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
547         }
548
549 #if 0
550         return_additional_info = BITSETW(params,0);
551         open_sattr = SVAL(params, 4);
552         open_time = make_unix_date3(params+8);
553 #endif
554         open_ofun = SVAL(params,12);
555         open_size = IVAL(params,14);
556         pname = &params[28];
557
558         if (IS_IPC(conn)) {
559                 reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
560                 goto out;
561         }
562
563         if (req->posix_pathnames) {
564                 srvstr_get_path_posix(ctx,
565                         params,
566                         req->flags2,
567                         &fname,
568                         pname,
569                         total_params - 28,
570                         STR_TERMINATE,
571                         &status);
572         } else {
573                 srvstr_get_path(ctx,
574                         params,
575                         req->flags2,
576                         &fname,
577                         pname,
578                         total_params - 28,
579                         STR_TERMINATE,
580                         &status);
581         }
582         if (!NT_STATUS_IS_OK(status)) {
583                 reply_nterror(req, status);
584                 goto out;
585         }
586
587         DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
588                 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
589                 (unsigned int)open_ofun, open_size));
590
591         if (ucf_flags & UCF_GMT_PATHNAME) {
592                 extract_snapshot_token(fname, &twrp);
593         }
594         status = smb1_strip_dfs_path(ctx, &ucf_flags, &fname);
595         if (!NT_STATUS_IS_OK(status)) {
596                 reply_nterror(req, status);
597                 goto out;
598         }
599         status = filename_convert_dirfsp(ctx,
600                                          conn,
601                                          fname,
602                                          ucf_flags,
603                                          twrp,
604                                          &dirfsp,
605                                          &smb_fname);
606         if (!NT_STATUS_IS_OK(status)) {
607                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
608                         reply_botherror(req,
609                                 NT_STATUS_PATH_NOT_COVERED,
610                                 ERRSRV, ERRbadpath);
611                         goto out;
612                 }
613                 reply_nterror(req, status);
614                 goto out;
615         }
616
617         if (open_ofun == 0) {
618                 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
619                 goto out;
620         }
621
622         if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
623                                          open_ofun,
624                                          &access_mask, &share_mode,
625                                          &create_disposition,
626                                          &create_options,
627                                          &private_flags)) {
628                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
629                 goto out;
630         }
631
632         /* Any data in this call is an EA list. */
633         if (total_data && (total_data != 4)) {
634                 if (total_data < 10) {
635                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
636                         goto out;
637                 }
638
639                 if (IVAL(pdata,0) > total_data) {
640                         DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
641                                 IVAL(pdata,0), (unsigned int)total_data));
642                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
643                         goto out;
644                 }
645
646                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
647                                        total_data - 4);
648                 if (!ea_list) {
649                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
650                         goto out;
651                 }
652
653                 if (!lp_ea_support(SNUM(conn))) {
654                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
655                         goto out;
656                 }
657
658                 if (!req->posix_pathnames &&
659                                 ea_list_has_invalid_name(ea_list)) {
660                         int param_len = 30;
661                         *pparams = (char *)SMB_REALLOC(*pparams, param_len);
662                         if(*pparams == NULL ) {
663                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
664                                 goto out;
665                         }
666                         params = *pparams;
667                         memset(params, '\0', param_len);
668                         send_trans2_replies(conn, req, STATUS_INVALID_EA_NAME,
669                                 params, param_len, NULL, 0, max_data_bytes);
670                         goto out;
671                 }
672         }
673
674         status = SMB_VFS_CREATE_FILE(
675                 conn,                                   /* conn */
676                 req,                                    /* req */
677                 dirfsp,                                 /* dirfsp */
678                 smb_fname,                              /* fname */
679                 access_mask,                            /* access_mask */
680                 share_mode,                             /* share_access */
681                 create_disposition,                     /* create_disposition*/
682                 create_options,                         /* create_options */
683                 open_attr,                              /* file_attributes */
684                 oplock_request,                         /* oplock_request */
685                 NULL,                                   /* lease */
686                 open_size,                              /* allocation_size */
687                 private_flags,
688                 NULL,                                   /* sd */
689                 ea_list,                                /* ea_list */
690                 &fsp,                                   /* result */
691                 &smb_action,                            /* psbuf */
692                 NULL, NULL);                            /* create context */
693
694         if (!NT_STATUS_IS_OK(status)) {
695                 if (open_was_deferred(req->xconn, req->mid)) {
696                         /* We have re-scheduled this call. */
697                         goto out;
698                 }
699
700                 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
701                         reply_openerror(req, status);
702                         goto out;
703                 }
704
705                 fsp = fcb_or_dos_open(
706                         req,
707                         smb_fname,
708                         access_mask,
709                         create_options,
710                         private_flags);
711                 if (fsp == NULL) {
712                         bool ok = defer_smb1_sharing_violation(req);
713                         if (ok) {
714                                 goto out;
715                         }
716                         reply_openerror(req, status);
717                         goto out;
718                 }
719
720                 smb_action = FILE_WAS_OPENED;
721         }
722
723         size = get_file_size_stat(&smb_fname->st);
724         fattr = fdos_mode(fsp);
725         mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
726         inode = smb_fname->st.st_ex_ino;
727         if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
728                 close_file_free(req, &fsp, ERROR_CLOSE);
729                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
730                 goto out;
731         }
732
733         /* Realloc the size of parameters and data we will return */
734         *pparams = (char *)SMB_REALLOC(*pparams, 30);
735         if(*pparams == NULL ) {
736                 reply_nterror(req, NT_STATUS_NO_MEMORY);
737                 goto out;
738         }
739         params = *pparams;
740
741         SSVAL(params,0,fsp->fnum);
742         SSVAL(params,2,fattr);
743         srv_put_dos_date2(params,4, mtime);
744         SIVAL(params,8, (uint32_t)size);
745         SSVAL(params,12,deny_mode);
746         SSVAL(params,14,0); /* open_type - file or directory. */
747         SSVAL(params,16,0); /* open_state - only valid for IPC device. */
748
749         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
750                 smb_action |= EXTENDED_OPLOCK_GRANTED;
751         }
752
753         SSVAL(params,18,smb_action);
754
755         /*
756          * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
757          */
758         SIVAL(params,20,inode);
759         SSVAL(params,24,0); /* Padding. */
760         if (flags & 8) {
761                 uint32_t ea_size = estimate_ea_size(smb_fname->fsp);
762                 SIVAL(params, 26, ea_size);
763         } else {
764                 SIVAL(params, 26, 0);
765         }
766
767         /* Send the required number of replies */
768         send_trans2_replies(conn, req, NT_STATUS_OK, params, 30, *ppdata, 0, max_data_bytes);
769  out:
770         TALLOC_FREE(smb_fname);
771 }
772
773 static NTSTATUS get_lanman2_dir_entry(TALLOC_CTX *ctx,
774                                 connection_struct *conn,
775                                 struct dptr_struct *dirptr,
776                                 uint16_t flags2,
777                                 const char *path_mask,
778                                 uint32_t dirtype,
779                                 int info_level,
780                                 bool requires_resume_key,
781                                 bool dont_descend,
782                                 bool ask_sharemode,
783                                 char **ppdata,
784                                 char *base_data,
785                                 char *end_data,
786                                 int space_remaining,
787                                 bool *got_exact_match,
788                                 int *last_entry_off,
789                                 struct ea_list *name_list)
790 {
791         uint8_t align = 4;
792         const bool do_pad = true;
793
794         if (info_level >= 1 && info_level <= 3) {
795                 /* No alignment on earlier info levels. */
796                 align = 1;
797         }
798
799         return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
800                                          path_mask, dirtype, info_level,
801                                          requires_resume_key, dont_descend, ask_sharemode,
802                                          true, align, do_pad,
803                                          ppdata, base_data, end_data,
804                                          space_remaining,
805                                          NULL,
806                                          got_exact_match,
807                                          last_entry_off, name_list, NULL);
808 }
809
810 /****************************************************************************
811  Reply to a TRANS2_FINDFIRST.
812 ****************************************************************************/
813
814 static void call_trans2findfirst(connection_struct *conn,
815                                  struct smb_request *req,
816                                  char **pparams, int total_params,
817                                  char **ppdata, int total_data,
818                                  unsigned int max_data_bytes)
819 {
820         /* We must be careful here that we don't return more than the
821                 allowed number of data bytes. If this means returning fewer than
822                 maxentries then so be it. We assume that the redirector has
823                 enough room for the fixed number of parameter bytes it has
824                 requested. */
825         struct smb_filename *smb_dname = NULL;
826         char *params = *pparams;
827         char *pdata = *ppdata;
828         char *data_end;
829         uint32_t dirtype;
830         int maxentries;
831         uint16_t findfirst_flags;
832         bool close_after_first;
833         bool close_if_end;
834         bool requires_resume_key;
835         int info_level;
836         char *directory = NULL;
837         char *mask = NULL;
838         char *p;
839         int last_entry_off=0;
840         int dptr_num = -1;
841         int numentries = 0;
842         int i;
843         bool finished = False;
844         bool dont_descend = False;
845         bool out_of_space = False;
846         int space_remaining;
847         struct ea_list *ea_list = NULL;
848         NTSTATUS ntstatus = NT_STATUS_OK;
849         bool ask_sharemode;
850         struct smbd_server_connection *sconn = req->sconn;
851         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
852         bool backup_priv = false;
853         bool as_root = false;
854         files_struct *fsp = NULL;
855         struct files_struct *dirfsp = NULL;
856         const struct loadparm_substitution *lp_sub =
857                 loadparm_s3_global_substitution();
858
859         if (total_params < 13) {
860                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
861                 goto out;
862         }
863
864         dirtype = SVAL(params,0);
865         maxentries = SVAL(params,2);
866         findfirst_flags = SVAL(params,4);
867         close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
868         close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
869         requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
870         backup_priv = ((findfirst_flags & FLAG_TRANS2_FIND_BACKUP_INTENT) &&
871                                 security_token_has_privilege(get_current_nttok(conn),
872                                                 SEC_PRIV_BACKUP));
873
874         info_level = SVAL(params,6);
875
876         DBG_NOTICE("dirtype = %"PRIx32", maxentries = %d, "
877                    "close_after_first=%d, close_if_end = %d "
878                    "requires_resume_key = %d backup_priv = %d level = 0x%x, "
879                    "max_data_bytes = %d\n",
880                    dirtype,
881                    maxentries,
882                    close_after_first,
883                    close_if_end,
884                    requires_resume_key,
885                    backup_priv,
886                    info_level,
887                    max_data_bytes);
888
889         if (!maxentries) {
890                 /* W2K3 seems to treat zero as 1. */
891                 maxentries = 1;
892         }
893
894         switch (info_level) {
895                 case SMB_FIND_INFO_STANDARD:
896                 case SMB_FIND_EA_SIZE:
897                 case SMB_FIND_EA_LIST:
898                 case SMB_FIND_FILE_DIRECTORY_INFO:
899                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
900                 case SMB_FIND_FILE_NAMES_INFO:
901                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
902                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
903                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
904                         break;
905                 case SMB_FIND_FILE_UNIX:
906                 case SMB_FIND_FILE_UNIX_INFO2:
907                         if (!lp_smb1_unix_extensions()) {
908                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
909                                 goto out;
910                         }
911                         if (!req->posix_pathnames) {
912                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
913                                 goto out;
914                         }
915                         break;
916                 default:
917                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
918                         goto out;
919         }
920
921         if (req->posix_pathnames) {
922                 srvstr_get_path_posix(talloc_tos(),
923                                 params,
924                                 req->flags2,
925                                 &directory,
926                                 params+12,
927                                 total_params - 12,
928                                 STR_TERMINATE,
929                                 &ntstatus);
930         } else {
931                 srvstr_get_path(talloc_tos(),
932                                 params,
933                                 req->flags2,
934                                 &directory,
935                                 params+12,
936                                 total_params - 12,
937                                 STR_TERMINATE,
938                                 &ntstatus);
939         }
940         if (!NT_STATUS_IS_OK(ntstatus)) {
941                 reply_nterror(req, ntstatus);
942                 goto out;
943         }
944
945         if (backup_priv) {
946                 become_root();
947                 as_root = true;
948         }
949         ntstatus = smb1_strip_dfs_path(talloc_tos(), &ucf_flags, &directory);
950         if (!NT_STATUS_IS_OK(ntstatus)) {
951                 reply_nterror(req, ntstatus);
952                 goto out;
953         }
954
955         ntstatus = filename_convert_smb1_search_path(talloc_tos(),
956                                                      conn,
957                                                      directory,
958                                                      ucf_flags,
959                                                      &dirfsp,
960                                                      &smb_dname,
961                                                      &mask);
962
963         if (!NT_STATUS_IS_OK(ntstatus)) {
964                 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
965                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
966                                         ERRSRV, ERRbadpath);
967                         goto out;
968                 }
969                 reply_nterror(req, ntstatus);
970                 goto out;
971         }
972
973         TALLOC_FREE(directory);
974         directory = smb_dname->base_name;
975
976         DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
977
978         if (info_level == SMB_FIND_EA_LIST) {
979                 uint32_t ea_size;
980
981                 if (total_data < 4) {
982                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
983                         goto out;
984                 }
985
986                 ea_size = IVAL(pdata,0);
987                 if (ea_size != total_data) {
988                         DBG_NOTICE("Rejecting EA request with incorrect "
989                                    "total_data=%d (should be %" PRIu32 ")\n",
990                                    total_data,
991                                    ea_size);
992                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
993                         goto out;
994                 }
995
996                 if (!lp_ea_support(SNUM(conn))) {
997                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
998                         goto out;
999                 }
1000
1001                 /* Pull out the list of names. */
1002                 ea_list = read_ea_name_list(talloc_tos(), pdata + 4, ea_size - 4);
1003                 if (!ea_list) {
1004                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1005                         goto out;
1006                 }
1007         }
1008
1009         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
1010                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1011                 goto out;
1012         }
1013
1014         *ppdata = (char *)SMB_REALLOC(
1015                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1016         if(*ppdata == NULL ) {
1017                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1018                 goto out;
1019         }
1020         pdata = *ppdata;
1021         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
1022         /*
1023          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
1024          * error.
1025          */
1026         memset(pdata + total_data, 0, ((max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data));
1027         /* Realloc the params space */
1028         *pparams = (char *)SMB_REALLOC(*pparams, 10);
1029         if (*pparams == NULL) {
1030                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1031                 goto out;
1032         }
1033         params = *pparams;
1034
1035         /*
1036          * Open an fsp on this directory for the dptr.
1037          */
1038         ntstatus = SMB_VFS_CREATE_FILE(
1039                         conn, /* conn */
1040                         req, /* req */
1041                         dirfsp, /* dirfsp */
1042                         smb_dname, /* dname */
1043                         FILE_LIST_DIRECTORY, /* access_mask */
1044                         FILE_SHARE_READ|
1045                         FILE_SHARE_WRITE, /* share_access */
1046                         FILE_OPEN, /* create_disposition*/
1047                         FILE_DIRECTORY_FILE, /* create_options */
1048                         FILE_ATTRIBUTE_DIRECTORY,/* file_attributes */
1049                         NO_OPLOCK, /* oplock_request */
1050                         NULL, /* lease */
1051                         0, /* allocation_size */
1052                         0, /* private_flags */
1053                         NULL, /* sd */
1054                         NULL, /* ea_list */
1055                         &fsp, /* result */
1056                         NULL, /* pinfo */
1057                         NULL, /* in_context */
1058                         NULL);/* out_context */
1059
1060         if (!NT_STATUS_IS_OK(ntstatus)) {
1061                 DBG_ERR("failed to open directory %s\n",
1062                         smb_fname_str_dbg(smb_dname));
1063                 reply_nterror(req, ntstatus);
1064                 goto out;
1065         }
1066
1067         /* Save the wildcard match and attribs we are using on this directory -
1068                 needed as lanman2 assumes these are being saved between calls */
1069
1070         ntstatus = dptr_create(conn,
1071                                 req,
1072                                 fsp, /* fsp */
1073                                 False,
1074                                 mask,
1075                                 dirtype,
1076                                 &fsp->dptr);
1077
1078         if (!NT_STATUS_IS_OK(ntstatus)) {
1079                 /*
1080                  * Use NULL here for the first parameter (req)
1081                  * as this is not a client visible handle so
1082                  * can'tbe part of an SMB1 chain.
1083                  */
1084                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
1085                 reply_nterror(req, ntstatus);
1086                 goto out;
1087         }
1088
1089         if (backup_priv) {
1090                 /* Remember this in case we have
1091                    to do a findnext. */
1092                 dptr_set_priv(fsp->dptr);
1093         }
1094
1095         dptr_num = dptr_dnum(fsp->dptr);
1096         DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
1097
1098         /* We don't need to check for VOL here as this is returned by
1099                 a different TRANS2 call. */
1100
1101         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1102                  directory,lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn))));
1103         if (in_list(directory,
1104                     lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn)),
1105                         dptr_case_sensitive(fsp->dptr))) {
1106                 dont_descend = True;
1107         }
1108
1109         p = pdata;
1110         space_remaining = max_data_bytes;
1111         out_of_space = False;
1112
1113         ask_sharemode = fsp_search_ask_sharemode(fsp);
1114
1115         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1116                 bool got_exact_match = False;
1117
1118                 /* this is a heuristic to avoid seeking the dirptr except when
1119                         absolutely necessary. It allows for a filename of about 40 chars */
1120                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1121                         out_of_space = True;
1122                         finished = False;
1123                 } else {
1124                         ntstatus = get_lanman2_dir_entry(talloc_tos(),
1125                                         conn,
1126                                         fsp->dptr,
1127                                         req->flags2,
1128                                         mask,dirtype,info_level,
1129                                         requires_resume_key,dont_descend,
1130                                         ask_sharemode,
1131                                         &p,pdata,data_end,
1132                                         space_remaining,
1133                                         &got_exact_match,
1134                                         &last_entry_off, ea_list);
1135                         if (NT_STATUS_EQUAL(ntstatus,
1136                                         NT_STATUS_ILLEGAL_CHARACTER)) {
1137                                 /*
1138                                  * Bad character conversion on name. Ignore this
1139                                  * entry.
1140                                  */
1141                                 continue;
1142                         }
1143                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
1144                                 out_of_space = true;
1145                         } else {
1146                                 finished = !NT_STATUS_IS_OK(ntstatus);
1147                         }
1148                 }
1149
1150                 if (!finished && !out_of_space) {
1151                         numentries++;
1152                 }
1153
1154                 /*
1155                  * As an optimisation if we know we aren't looking
1156                  * for a wildcard name (ie. the name matches the wildcard exactly)
1157                  * then we can finish on any (first) match.
1158                  * This speeds up large directory searches. JRA.
1159                  */
1160
1161                 if (got_exact_match) {
1162                         finished = true;
1163                 }
1164
1165                 /* Ensure space_remaining never goes -ve. */
1166                 if (PTR_DIFF(p,pdata) > max_data_bytes) {
1167                         space_remaining = 0;
1168                         out_of_space = true;
1169                 } else {
1170                         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1171                 }
1172         }
1173
1174         /* Check if we can close the dirptr */
1175         if(close_after_first || (finished && close_if_end)) {
1176                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1177                 dptr_num = -1;
1178                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
1179         }
1180
1181         /*
1182          * If there are no matching entries we must return ERRDOS/ERRbadfile -
1183          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
1184          * the protocol level is less than NT1. Tested with smbclient. JRA.
1185          * This should fix the OS/2 client bug #2335.
1186          */
1187
1188         if(numentries == 0) {
1189                 dptr_num = -1;
1190                 /*
1191                  * We may have already closed the file in the
1192                  * close_after_first or finished case above.
1193                  */
1194                 if (fsp != NULL) {
1195                         close_file_free(NULL, &fsp, NORMAL_CLOSE);
1196                 }
1197                 if (get_Protocol() < PROTOCOL_NT1) {
1198                         reply_force_doserror(req, ERRDOS, ERRnofiles);
1199                         goto out;
1200                 } else {
1201                         reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
1202                                         ERRDOS, ERRbadfile);
1203                         goto out;
1204                 }
1205         }
1206
1207         /* At this point pdata points to numentries directory entries. */
1208
1209         /* Set up the return parameter block */
1210         SSVAL(params,0,dptr_num);
1211         SSVAL(params,2,numentries);
1212         SSVAL(params,4,finished);
1213         SSVAL(params,6,0); /* Never an EA error */
1214         SSVAL(params,8,last_entry_off);
1215
1216         send_trans2_replies(conn, req, NT_STATUS_OK, params, 10, pdata, PTR_DIFF(p,pdata),
1217                             max_data_bytes);
1218
1219         if ((! *directory) && dptr_path(sconn, dptr_num)) {
1220                 directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
1221                 if (!directory) {
1222                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1223                 }
1224         }
1225
1226         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1227                 smb_fn_name(req->cmd),
1228                 mask, directory, dirtype, numentries ) );
1229
1230         /*
1231          * Force a name mangle here to ensure that the
1232          * mask as an 8.3 name is top of the mangled cache.
1233          * The reasons for this are subtle. Don't remove
1234          * this code unless you know what you are doing
1235          * (see PR#13758). JRA.
1236          */
1237
1238         if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
1239                 char mangled_name[13];
1240                 name_to_8_3(mask, mangled_name, True, conn->params);
1241         }
1242  out:
1243
1244         if (as_root) {
1245                 unbecome_root();
1246         }
1247
1248         TALLOC_FREE(smb_dname);
1249         return;
1250 }
1251
1252 static bool smbd_dptr_name_equal(struct dptr_struct *dptr,
1253                                  const char *name1,
1254                                  const char *name2)
1255 {
1256         bool equal;
1257
1258         if (dptr_case_sensitive(dptr)) {
1259                 equal = (strcmp(name1, name2) == 0);
1260         } else {
1261                 equal = strequal(name1, name2);
1262         }
1263
1264         return equal;
1265 }
1266
1267 /****************************************************************************
1268  Reply to a TRANS2_FINDNEXT.
1269 ****************************************************************************/
1270
1271 static void call_trans2findnext(connection_struct *conn,
1272                                 struct smb_request *req,
1273                                 char **pparams, int total_params,
1274                                 char **ppdata, int total_data,
1275                                 unsigned int max_data_bytes)
1276 {
1277         /* We must be careful here that we don't return more than the
1278                 allowed number of data bytes. If this means returning fewer than
1279                 maxentries then so be it. We assume that the redirector has
1280                 enough room for the fixed number of parameter bytes it has
1281                 requested. */
1282         char *params = *pparams;
1283         char *pdata = *ppdata;
1284         char *data_end;
1285         int dptr_num;
1286         int maxentries;
1287         uint16_t info_level;
1288         uint32_t resume_key;
1289         uint16_t findnext_flags;
1290         bool close_after_request;
1291         bool close_if_end;
1292         bool requires_resume_key;
1293         bool continue_bit;
1294         char *resume_name = NULL;
1295         const char *mask = NULL;
1296         const char *directory = NULL;
1297         char *p = NULL;
1298         uint16_t dirtype;
1299         int numentries = 0;
1300         int i, last_entry_off=0;
1301         bool finished = False;
1302         bool dont_descend = False;
1303         bool out_of_space = False;
1304         int space_remaining;
1305         struct ea_list *ea_list = NULL;
1306         NTSTATUS ntstatus = NT_STATUS_OK;
1307         bool ask_sharemode;
1308         TALLOC_CTX *ctx = talloc_tos();
1309         struct smbd_server_connection *sconn = req->sconn;
1310         bool backup_priv = false;
1311         bool as_root = false;
1312         files_struct *fsp = NULL;
1313         const struct loadparm_substitution *lp_sub =
1314                 loadparm_s3_global_substitution();
1315
1316         if (total_params < 13) {
1317                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1318                 return;
1319         }
1320
1321         dptr_num = SVAL(params,0);
1322         maxentries = SVAL(params,2);
1323         info_level = SVAL(params,4);
1324         resume_key = IVAL(params,6);
1325         findnext_flags = SVAL(params,10);
1326         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1327         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1328         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1329         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1330
1331         if (!continue_bit) {
1332                 /* We only need resume_name if continue_bit is zero. */
1333                 if (req->posix_pathnames) {
1334                         srvstr_get_path_posix(ctx,
1335                                 params,
1336                                 req->flags2,
1337                                 &resume_name,
1338                                 params+12,
1339                                 total_params - 12,
1340                                 STR_TERMINATE,
1341                                 &ntstatus);
1342                 } else {
1343                         srvstr_get_path(ctx,
1344                                 params,
1345                                 req->flags2,
1346                                 &resume_name,
1347                                 params+12,
1348                                 total_params - 12,
1349                                 STR_TERMINATE,
1350                                 &ntstatus);
1351                 }
1352                 if (!NT_STATUS_IS_OK(ntstatus)) {
1353                         /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
1354                            complain (it thinks we're asking for the directory above the shared
1355                            path or an invalid name). Catch this as the resume name is only compared, never used in
1356                            a file access. JRA. */
1357                         srvstr_pull_talloc(ctx, params, req->flags2,
1358                                 &resume_name, params+12,
1359                                 total_params - 12,
1360                                 STR_TERMINATE);
1361
1362                         if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
1363                                 reply_nterror(req, ntstatus);
1364                                 return;
1365                         }
1366                 }
1367         }
1368
1369         DBG_NOTICE("dirhandle = %d, max_data_bytes = %u, maxentries = %d, "
1370                    "close_after_request=%d, close_if_end = %d "
1371                    "requires_resume_key = %d resume_key = %d "
1372                    "resume name = %s continue=%d level = %d\n",
1373                    dptr_num,
1374                    max_data_bytes,
1375                    maxentries,
1376                    close_after_request,
1377                    close_if_end,
1378                    requires_resume_key,
1379                    resume_key,
1380                    resume_name ? resume_name : "(NULL)",
1381                    continue_bit,
1382                    info_level);
1383
1384         if (!maxentries) {
1385                 /* W2K3 seems to treat zero as 1. */
1386                 maxentries = 1;
1387         }
1388
1389         switch (info_level) {
1390                 case SMB_FIND_INFO_STANDARD:
1391                 case SMB_FIND_EA_SIZE:
1392                 case SMB_FIND_EA_LIST:
1393                 case SMB_FIND_FILE_DIRECTORY_INFO:
1394                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1395                 case SMB_FIND_FILE_NAMES_INFO:
1396                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1397                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1398                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1399                         break;
1400                 case SMB_FIND_FILE_UNIX:
1401                 case SMB_FIND_FILE_UNIX_INFO2:
1402                         if (!lp_smb1_unix_extensions()) {
1403                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1404                                 return;
1405                         }
1406                         if (!req->posix_pathnames) {
1407                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1408                                 return;
1409                         }
1410                         break;
1411                 default:
1412                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1413                         return;
1414         }
1415
1416         if (info_level == SMB_FIND_EA_LIST) {
1417                 uint32_t ea_size;
1418
1419                 if (total_data < 4) {
1420                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1421                         return;
1422                 }
1423
1424                 ea_size = IVAL(pdata,0);
1425                 if (ea_size != total_data) {
1426                         DBG_NOTICE("Rejecting EA request with incorrect "
1427                                    "total_data=%d (should be %" PRIu32 ")\n",
1428                                    total_data,
1429                                    ea_size);
1430                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1431                         return;
1432                 }
1433
1434                 if (!lp_ea_support(SNUM(conn))) {
1435                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1436                         return;
1437                 }
1438
1439                 /* Pull out the list of names. */
1440                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
1441                 if (!ea_list) {
1442                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1443                         return;
1444                 }
1445         }
1446
1447         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
1448                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1449                 return;
1450         }
1451
1452         *ppdata = (char *)SMB_REALLOC(
1453                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1454         if(*ppdata == NULL) {
1455                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1456                 return;
1457         }
1458
1459         pdata = *ppdata;
1460         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
1461
1462         /*
1463          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
1464          * error.
1465          */
1466         memset(pdata + total_data, 0, (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data);
1467         /* Realloc the params space */
1468         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
1469         if(*pparams == NULL ) {
1470                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1471                 return;
1472         }
1473
1474         params = *pparams;
1475
1476         /* Check that the dptr is valid */
1477         fsp = dptr_fetch_lanman2_fsp(sconn, dptr_num);
1478         if (fsp == NULL) {
1479                 reply_nterror(req, STATUS_NO_MORE_FILES);
1480                 return;
1481         }
1482
1483         directory = dptr_path(sconn, dptr_num);
1484
1485         /* Get the wildcard mask from the dptr */
1486         if((mask = dptr_wcard(sconn, dptr_num))== NULL) {
1487                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1488                 reply_nterror(req, STATUS_NO_MORE_FILES);
1489                 return;
1490         }
1491
1492         /* Get the attr mask from the dptr */
1493         dirtype = dptr_attr(sconn, dptr_num);
1494
1495         backup_priv = dptr_get_priv(fsp->dptr);
1496
1497         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX) "
1498                 "backup_priv = %d\n",
1499                 dptr_num, mask, dirtype,
1500                 (long)fsp->dptr,
1501                 (int)backup_priv));
1502
1503         /* We don't need to check for VOL here as this is returned by
1504                 a different TRANS2 call. */
1505
1506         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1507                  directory,lp_dont_descend(ctx, lp_sub, SNUM(conn))));
1508         if (in_list(directory,lp_dont_descend(ctx, lp_sub, SNUM(conn)),
1509                         dptr_case_sensitive(fsp->dptr)))
1510                 dont_descend = True;
1511
1512         p = pdata;
1513         space_remaining = max_data_bytes;
1514         out_of_space = False;
1515
1516         if (backup_priv) {
1517                 become_root();
1518                 as_root = true;
1519         }
1520
1521         /*
1522          * Seek to the correct position. We no longer use the resume key but
1523          * depend on the last file name instead.
1524          */
1525
1526         if(!continue_bit && resume_name && *resume_name) {
1527                 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1528                 char *last_name_sent = NULL;
1529                 bool sequential;
1530
1531                 /*
1532                  * Remember, name_to_8_3 is called by
1533                  * get_lanman2_dir_entry(), so the resume name
1534                  * could be mangled. Ensure we check the unmangled name.
1535                  */
1536
1537                 if (!posix_open &&
1538                                 mangle_is_mangled(resume_name, conn->params)) {
1539                         char *new_resume_name = NULL;
1540                         mangle_lookup_name_from_8_3(ctx,
1541                                                 resume_name,
1542                                                 &new_resume_name,
1543                                                 conn->params);
1544                         if (new_resume_name) {
1545                                 resume_name = new_resume_name;
1546                         }
1547                 }
1548
1549                 /*
1550                  * Fix for NT redirector problem triggered by resume key indexes
1551                  * changing between directory scans. We now return a resume key of 0
1552                  * and instead look for the filename to continue from (also given
1553                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1554                  * findfirst/findnext (as is usual) then the directory pointer
1555                  * should already be at the correct place.
1556                  */
1557
1558                 last_name_sent = smbd_dirptr_get_last_name_sent(fsp->dptr);
1559                 sequential = smbd_dptr_name_equal(fsp->dptr,
1560                                                   resume_name,
1561                                                   last_name_sent);
1562                 if (!sequential) {
1563                         struct stat_ex st;
1564                         char *name = NULL;
1565                         bool found = false;
1566
1567                         dptr_RewindDir(fsp->dptr);
1568
1569                         while ((name = dptr_ReadDirName(talloc_tos(),
1570                                                         fsp->dptr,
1571                                                         &st)) != NULL) {
1572                                 found = smbd_dptr_name_equal(fsp->dptr,
1573                                                              resume_name,
1574                                                              name);
1575                                 TALLOC_FREE(name);
1576                                 if (found) {
1577                                         break;
1578                                 }
1579                         }
1580
1581                         if (!found) {
1582                                 /*
1583                                  * We got a name that used to exist
1584                                  * but does not anymore. Just start
1585                                  * from the beginning. Shown by the
1586                                  * "raw.search.os2 delete" smbtorture
1587                                  * test.
1588                                  */
1589                                 dptr_RewindDir(fsp->dptr);
1590                         }
1591                 }
1592         } /* end if resume_name && !continue_bit */
1593
1594         ask_sharemode = fsp_search_ask_sharemode(fsp);
1595
1596         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1597                 bool got_exact_match = False;
1598
1599                 /* this is a heuristic to avoid seeking the fsp->dptr except when
1600                         absolutely necessary. It allows for a filename of about 40 chars */
1601                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1602                         out_of_space = True;
1603                         finished = False;
1604                 } else {
1605                         ntstatus = get_lanman2_dir_entry(ctx,
1606                                                 conn,
1607                                                 fsp->dptr,
1608                                                 req->flags2,
1609                                                 mask,dirtype,info_level,
1610                                                 requires_resume_key,dont_descend,
1611                                                 ask_sharemode,
1612                                                 &p,pdata,data_end,
1613                                                 space_remaining,
1614                                                 &got_exact_match,
1615                                                 &last_entry_off, ea_list);
1616                         if (NT_STATUS_EQUAL(ntstatus,
1617                                         NT_STATUS_ILLEGAL_CHARACTER)) {
1618                                 /*
1619                                  * Bad character conversion on name. Ignore this
1620                                  * entry.
1621                                  */
1622                                 continue;
1623                         }
1624                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
1625                                 out_of_space = true;
1626                         } else {
1627                                 finished = !NT_STATUS_IS_OK(ntstatus);
1628                         }
1629                 }
1630
1631                 if (!finished && !out_of_space) {
1632                         numentries++;
1633                 }
1634
1635                 /*
1636                  * As an optimisation if we know we aren't looking
1637                  * for a wildcard name (ie. the name matches the wildcard exactly)
1638                  * then we can finish on any (first) match.
1639                  * This speeds up large directory searches. JRA.
1640                  */
1641
1642                 if (got_exact_match) {
1643                         finished = true;
1644                 }
1645
1646                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1647         }
1648
1649         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1650                 smb_fn_name(req->cmd),
1651                 mask, directory, dirtype, numentries ) );
1652
1653         /* Check if we can close the fsp->dptr */
1654         if(close_after_request || (finished && close_if_end)) {
1655                 DBG_INFO("closing dptr_num = %d\n", dptr_num);
1656                 dptr_num = -1;
1657                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
1658         }
1659
1660         if (as_root) {
1661                 unbecome_root();
1662         }
1663
1664         /* Set up the return parameter block */
1665         SSVAL(params,0,numentries);
1666         SSVAL(params,2,finished);
1667         SSVAL(params,4,0); /* Never an EA error */
1668         SSVAL(params,6,last_entry_off);
1669
1670         send_trans2_replies(conn, req, NT_STATUS_OK, params, 8, pdata, PTR_DIFF(p,pdata),
1671                             max_data_bytes);
1672
1673         return;
1674 }
1675
1676 /****************************************************************************
1677  Reply to a TRANS2_QFSINFO (query filesystem info).
1678 ****************************************************************************/
1679
1680 static void call_trans2qfsinfo(connection_struct *conn,
1681                                struct smb_request *req,
1682                                char **pparams, int total_params,
1683                                char **ppdata, int total_data,
1684                                unsigned int max_data_bytes)
1685 {
1686         char *params = *pparams;
1687         uint16_t info_level;
1688         int data_len = 0;
1689         size_t fixed_portion;
1690         NTSTATUS status;
1691
1692         if (total_params < 2) {
1693                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1694                 return;
1695         }
1696
1697         info_level = SVAL(params,0);
1698
1699         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
1700                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
1701                         DEBUG(0,("call_trans2qfsinfo: encryption required "
1702                                 "and info level 0x%x sent.\n",
1703                                 (unsigned int)info_level));
1704                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1705                         return;
1706                 }
1707         }
1708
1709         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1710
1711         status = smbd_do_qfsinfo(req->xconn, conn, req,
1712                                  info_level,
1713                                  req->flags2,
1714                                  max_data_bytes,
1715                                  &fixed_portion,
1716                                  NULL,
1717                                  ppdata, &data_len);
1718         if (!NT_STATUS_IS_OK(status)) {
1719                 reply_nterror(req, status);
1720                 return;
1721         }
1722
1723         send_trans2_replies(conn, req, NT_STATUS_OK, params, 0, *ppdata, data_len,
1724                             max_data_bytes);
1725
1726         DEBUG( 4, ( "%s info_level = %d\n",
1727                     smb_fn_name(req->cmd), info_level) );
1728
1729         return;
1730 }
1731
1732 /****************************************************************************
1733  Reply to a TRANS2_SETFSINFO (set filesystem info).
1734 ****************************************************************************/
1735
1736 static void call_trans2setfsinfo(connection_struct *conn,
1737                                  struct smb_request *req,
1738                                  char **pparams, int total_params,
1739                                  char **ppdata, int total_data,
1740                                  unsigned int max_data_bytes)
1741 {
1742         const struct loadparm_substitution *lp_sub =
1743                 loadparm_s3_global_substitution();
1744         struct smbXsrv_connection *xconn = req->xconn;
1745         char *pdata = *ppdata;
1746         char *params = *pparams;
1747         uint16_t info_level;
1748
1749         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
1750                   lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
1751
1752         /*  */
1753         if (total_params < 4) {
1754                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
1755                         total_params));
1756                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1757                 return;
1758         }
1759
1760         info_level = SVAL(params,2);
1761
1762         if (IS_IPC(conn)) {
1763                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
1764                                 info_level != SMB_SET_CIFS_UNIX_INFO) {
1765                         DEBUG(0,("call_trans2setfsinfo: not an allowed "
1766                                 "info level (0x%x) on IPC$.\n",
1767                                 (unsigned int)info_level));
1768                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1769                         return;
1770                 }
1771         }
1772
1773         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
1774                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
1775                         DEBUG(0,("call_trans2setfsinfo: encryption required "
1776                                 "and info level 0x%x sent.\n",
1777                                 (unsigned int)info_level));
1778                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1779                         return;
1780                 }
1781         }
1782
1783         switch(info_level) {
1784                 case SMB_SET_CIFS_UNIX_INFO:
1785                         if (!lp_smb1_unix_extensions()) {
1786                                 DEBUG(2,("call_trans2setfsinfo: "
1787                                         "SMB_SET_CIFS_UNIX_INFO is invalid with "
1788                                         "unix extensions off\n"));
1789                                 reply_nterror(req,
1790                                               NT_STATUS_INVALID_LEVEL);
1791                                 return;
1792                         }
1793
1794                         /* There should be 12 bytes of capabilities set. */
1795                         if (total_data < 12) {
1796                                 reply_nterror(
1797                                         req,
1798                                         NT_STATUS_INVALID_PARAMETER);
1799                                 return;
1800                         }
1801                         xconn->smb1.unix_info.client_major = SVAL(pdata,0);
1802                         xconn->smb1.unix_info.client_minor = SVAL(pdata,2);
1803                         xconn->smb1.unix_info.client_cap_low = IVAL(pdata,4);
1804                         xconn->smb1.unix_info.client_cap_high = IVAL(pdata,8);
1805
1806                         /* Just print these values for now. */
1807                         DBG_DEBUG("set unix_info info. "
1808                                   "major = %"PRIu16", minor = %"PRIu16
1809                                   "cap_low = 0x%"PRIx32", "
1810                                   "cap_high = 0x%"PRIx32"\n",
1811                                   xconn->smb1.unix_info.client_major,
1812                                   xconn->smb1.unix_info.client_minor,
1813                                   xconn->smb1.unix_info.client_cap_low,
1814                                   xconn->smb1.unix_info.client_cap_high);
1815
1816                         /*
1817                          * Here is where we must switch to posix
1818                          * pathname processing...
1819                          */
1820                         if (xconn->smb1.unix_info.client_cap_low &
1821                             CIFS_UNIX_POSIX_PATHNAMES_CAP)
1822                         {
1823                                 lp_set_posix_pathnames();
1824                                 mangle_change_to_posix();
1825                         }
1826
1827                         if ((xconn->smb1.unix_info.client_cap_low &
1828                              CIFS_UNIX_FCNTL_LOCKS_CAP) &&
1829                             !(xconn->smb1.unix_info.client_cap_low &
1830                               CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP))
1831                         {
1832                                 /* Client that knows how to do posix locks,
1833                                  * but not posix open/mkdir operations. Set a
1834                                  * default type for read/write checks. */
1835
1836                                 lp_set_posix_default_cifsx_readwrite_locktype(
1837                                         POSIX_LOCK);
1838
1839                         }
1840                         break;
1841
1842                 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
1843                         {
1844                                 NTSTATUS status;
1845                                 size_t param_len = 0;
1846                                 size_t data_len = total_data;
1847
1848                                 if (!lp_smb1_unix_extensions()) {
1849                                         reply_nterror(
1850                                                 req,
1851                                                 NT_STATUS_INVALID_LEVEL);
1852                                         return;
1853                                 }
1854
1855                                 if (lp_server_smb_encrypt(SNUM(conn)) ==
1856                                     SMB_ENCRYPTION_OFF) {
1857                                         reply_nterror(
1858                                                 req,
1859                                                 NT_STATUS_NOT_SUPPORTED);
1860                                         return;
1861                                 }
1862
1863                                 if (xconn->smb1.echo_handler.trusted_fde) {
1864                                         DEBUG( 2,("call_trans2setfsinfo: "
1865                                                 "request transport encryption disabled"
1866                                                 "with 'fork echo handler = yes'\n"));
1867                                         reply_nterror(
1868                                                 req,
1869                                                 NT_STATUS_NOT_SUPPORTED);
1870                                         return;
1871                                 }
1872
1873                                 DEBUG( 4,("call_trans2setfsinfo: "
1874                                         "request transport encryption.\n"));
1875
1876                                 status = srv_request_encryption_setup(conn,
1877                                                                 (unsigned char **)ppdata,
1878                                                                 &data_len,
1879                                                                 (unsigned char **)pparams,
1880                                                                 &param_len);
1881
1882                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
1883                                                 !NT_STATUS_IS_OK(status)) {
1884                                         reply_nterror(req, status);
1885                                         return;
1886                                 }
1887
1888                                 send_trans2_replies(conn, req,
1889                                                 NT_STATUS_OK,
1890                                                 *pparams,
1891                                                 param_len,
1892                                                 *ppdata,
1893                                                 data_len,
1894                                                 max_data_bytes);
1895
1896                                 if (NT_STATUS_IS_OK(status)) {
1897                                         /* Server-side transport
1898                                          * encryption is now *on*. */
1899                                         status = srv_encryption_start(conn);
1900                                         if (!NT_STATUS_IS_OK(status)) {
1901                                                 char *reason = talloc_asprintf(talloc_tos(),
1902                                                                                "Failure in setting "
1903                                                                                "up encrypted transport: %s",
1904                                                                                nt_errstr(status));
1905                                                 exit_server_cleanly(reason);
1906                                         }
1907                                 }
1908                                 return;
1909                         }
1910
1911                 case SMB_FS_QUOTA_INFORMATION:
1912                         {
1913                                 NTSTATUS status;
1914                                 DATA_BLOB qdata = {
1915                                                 .data = (uint8_t *)pdata,
1916                                                 .length = total_data
1917                                 };
1918                                 files_struct *fsp = NULL;
1919                                 fsp = file_fsp(req, SVAL(params,0));
1920
1921                                 status = smb_set_fsquota(conn,
1922                                                         req,
1923                                                         fsp,
1924                                                         &qdata);
1925                                 if (!NT_STATUS_IS_OK(status)) {
1926                                         reply_nterror(req, status);
1927                                         return;
1928                                 }
1929                                 break;
1930                         }
1931                 default:
1932                         DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
1933                                 info_level));
1934                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1935                         return;
1936                         break;
1937         }
1938
1939         /*
1940          * sending this reply works fine,
1941          * but I'm not sure it's the same
1942          * like windows do...
1943          * --metze
1944          */
1945         reply_smb1_outbuf(req, 10, 0);
1946 }
1947
1948 /****************************************************************************
1949  Reply to a TRANSACT2_QFILEINFO on a PIPE !
1950 ****************************************************************************/
1951
1952 static void call_trans2qpipeinfo(connection_struct *conn,
1953                                  struct smb_request *req,
1954                                  files_struct *fsp,
1955                                  uint16_t info_level,
1956                                  unsigned int tran_call,
1957                                  char **pparams, int total_params,
1958                                  char **ppdata, int total_data,
1959                                  unsigned int max_data_bytes)
1960 {
1961         char *params = *pparams;
1962         char *pdata = *ppdata;
1963         unsigned int data_size = 0;
1964         unsigned int param_size = 2;
1965
1966         if (!fsp_is_np(fsp)) {
1967                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1968                 return;
1969         }
1970
1971         *pparams = (char *)SMB_REALLOC(*pparams,2);
1972         if (*pparams == NULL) {
1973                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1974                 return;
1975         }
1976         params = *pparams;
1977         SSVAL(params,0,0);
1978         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
1979                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1980                 return;
1981         }
1982         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
1983         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
1984         if (*ppdata == NULL ) {
1985                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1986                 return;
1987         }
1988         pdata = *ppdata;
1989
1990         switch (info_level) {
1991                 case SMB_FILE_STANDARD_INFORMATION:
1992                         memset(pdata,0,24);
1993                         SOFF_T(pdata,0,4096LL);
1994                         SIVAL(pdata,16,1);
1995                         SIVAL(pdata,20,1);
1996                         data_size = 24;
1997                         break;
1998
1999                 default:
2000                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2001                         return;
2002         }
2003
2004         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
2005                             max_data_bytes);
2006
2007         return;
2008 }
2009
2010 static void handle_trans2qfilepathinfo_result(
2011         connection_struct *conn,
2012         struct smb_request *req,
2013         uint16_t info_level,
2014         NTSTATUS status,
2015         char *pdata,
2016         int data_return_size,
2017         size_t fixed_portion,
2018         unsigned int max_data_bytes)
2019 {
2020         char params[2] = { 0, 0, };
2021         int param_size = 2;
2022
2023         /*
2024          * draft-leach-cifs-v1-spec-02.txt
2025          * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
2026          * says:
2027          *
2028          *  The requested information is placed in the Data portion of the
2029          *  transaction response. For the information levels greater than 0x100,
2030          *  the transaction response has 1 parameter word which should be
2031          *  ignored by the client.
2032          *
2033          * However Windows only follows this rule for the IS_NAME_VALID call.
2034          */
2035         switch (info_level) {
2036         case SMB_INFO_IS_NAME_VALID:
2037                 param_size = 0;
2038                 break;
2039         }
2040
2041         if (!NT_STATUS_IS_OK(status)) {
2042                 if (open_was_deferred(req->xconn, req->mid)) {
2043                         /* We have re-scheduled this call. */
2044                         return;
2045                 }
2046                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2047                         bool ok = defer_smb1_sharing_violation(req);
2048                         if (ok) {
2049                                 return;
2050                         }
2051                 }
2052                 reply_nterror(req, status);
2053                 return;
2054         }
2055
2056         if (fixed_portion > max_data_bytes) {
2057                 reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
2058                 return;
2059         }
2060
2061         send_trans2_replies(
2062                 conn,
2063                 req,
2064                 NT_STATUS_OK,
2065                 params,
2066                 param_size,
2067                 pdata,
2068                 data_return_size,
2069                 max_data_bytes);
2070 }
2071
2072 /****************************************************************************
2073  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2074  file name or file id).
2075 ****************************************************************************/
2076
2077 static void call_trans2qfilepathinfo(connection_struct *conn,
2078                                      struct smb_request *req,
2079                                      unsigned int tran_call,
2080                                      uint16_t info_level,
2081                                      struct smb_filename *smb_fname,
2082                                      struct files_struct *fsp,
2083                                      bool delete_pending,
2084                                      struct timespec write_time_ts,
2085                                      char **pparams, int total_params,
2086                                      char **ppdata, int total_data,
2087                                      unsigned int max_data_bytes)
2088 {
2089         char *params = *pparams;
2090         char *pdata = *ppdata;
2091         unsigned int data_size = 0;
2092         struct ea_list *ea_list = NULL;
2093         size_t fixed_portion;
2094         NTSTATUS status = NT_STATUS_OK;
2095
2096         DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
2097                  "total_data=%d\n", smb_fname_str_dbg(smb_fname),
2098                  fsp_fnum_dbg(fsp),
2099                  info_level,tran_call,total_data));
2100
2101         /* Pull out any data sent here before we realloc. */
2102         switch (info_level) {
2103                 case SMB_INFO_QUERY_EAS_FROM_LIST:
2104                 {
2105                         /* Pull any EA list from the data portion. */
2106                         uint32_t ea_size;
2107
2108                         if (total_data < 4) {
2109                                 reply_nterror(
2110                                         req, NT_STATUS_INVALID_PARAMETER);
2111                                 return;
2112                         }
2113                         ea_size = IVAL(pdata,0);
2114
2115                         if (total_data > 0 && ea_size != total_data) {
2116                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
2117 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2118                                 reply_nterror(
2119                                         req, NT_STATUS_INVALID_PARAMETER);
2120                                 return;
2121                         }
2122
2123                         if (!lp_ea_support(SNUM(conn))) {
2124                                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2125                                 return;
2126                         }
2127
2128                         /* Pull out the list of names. */
2129                         ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
2130                         if (!ea_list) {
2131                                 reply_nterror(
2132                                         req, NT_STATUS_INVALID_PARAMETER);
2133                                 return;
2134                         }
2135                         break;
2136                 }
2137
2138                 default:
2139                         break;
2140         }
2141
2142         *pparams = (char *)SMB_REALLOC(*pparams,2);
2143         if (*pparams == NULL) {
2144                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2145                 return;
2146         }
2147         params = *pparams;
2148         SSVAL(params,0,0);
2149
2150         if ((info_level & SMB2_INFO_SPECIAL) == SMB2_INFO_SPECIAL) {
2151                 /*
2152                  * We use levels that start with 0xFF00
2153                  * internally to represent SMB2 specific levels
2154                  */
2155                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2156                 return;
2157         }
2158
2159         status = smbd_do_qfilepathinfo(conn, req, req, info_level,
2160                                        fsp, smb_fname,
2161                                        delete_pending, write_time_ts,
2162                                        ea_list,
2163                                        req->flags2, max_data_bytes,
2164                                        &fixed_portion,
2165                                        ppdata, &data_size);
2166
2167         handle_trans2qfilepathinfo_result(
2168                 conn,
2169                 req,
2170                 info_level,
2171                 status,
2172                 *ppdata,
2173                 data_size,
2174                 fixed_portion,
2175                 max_data_bytes);
2176 }
2177
2178 static NTSTATUS smb_q_unix_basic(
2179         struct connection_struct *conn,
2180         struct smb_request *req,
2181         struct smb_filename *smb_fname,
2182         struct files_struct *fsp,
2183         char **ppdata,
2184         int *ptotal_data)
2185 {
2186         const int total_data = 100;
2187
2188         *ppdata = SMB_REALLOC(*ppdata, total_data);
2189         if (*ppdata == NULL) {
2190                 return NT_STATUS_NO_MEMORY;
2191         }
2192         store_file_unix_basic(conn, *ppdata, fsp, &smb_fname->st);
2193
2194         *ptotal_data = total_data;
2195
2196         return NT_STATUS_OK;
2197 }
2198
2199 static NTSTATUS smb_q_unix_info2(
2200         struct connection_struct *conn,
2201         struct smb_request *req,
2202         struct smb_filename *smb_fname,
2203         struct files_struct *fsp,
2204         char **ppdata,
2205         int *ptotal_data)
2206 {
2207         const int total_data = 116;
2208
2209         *ppdata = SMB_REALLOC(*ppdata, total_data);
2210         if (*ppdata == NULL) {
2211                 return NT_STATUS_NO_MEMORY;
2212         }
2213         store_file_unix_basic_info2(conn, *ppdata, fsp, &smb_fname->st);
2214
2215         *ptotal_data = total_data;
2216
2217         return NT_STATUS_OK;
2218 }
2219
2220 #if defined(HAVE_POSIX_ACLS)
2221 /****************************************************************************
2222  Utility function to open a fsp for a POSIX handle operation.
2223 ****************************************************************************/
2224
2225 static NTSTATUS get_posix_fsp(connection_struct *conn,
2226                               struct smb_request *req,
2227                               struct smb_filename *smb_fname,
2228                               uint32_t access_mask,
2229                               files_struct **ret_fsp)
2230 {
2231         NTSTATUS status;
2232         uint32_t create_disposition = FILE_OPEN;
2233         uint32_t share_access = FILE_SHARE_READ|
2234                                 FILE_SHARE_WRITE|
2235                                 FILE_SHARE_DELETE;
2236         struct smb2_create_blobs *posx = NULL;
2237
2238         /*
2239          * Only FILE_FLAG_POSIX_SEMANTICS matters on existing files,
2240          * but set reasonable defaults.
2241          */
2242         uint32_t file_attributes = 0664;
2243         uint32_t oplock = NO_OPLOCK;
2244         uint32_t create_options = FILE_NON_DIRECTORY_FILE;
2245
2246         /* File or directory must exist. */
2247         if (!VALID_STAT(smb_fname->st)) {
2248                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2249         }
2250         /* Cannot be a symlink. */
2251         if (S_ISLNK(smb_fname->st.st_ex_mode)) {
2252                 return NT_STATUS_ACCESS_DENIED;
2253         }
2254         /* Set options correctly for directory open. */
2255         if (S_ISDIR(smb_fname->st.st_ex_mode)) {
2256                 /*
2257                  * Only FILE_FLAG_POSIX_SEMANTICS matters on existing
2258                  * directories, but set reasonable defaults.
2259                  */
2260                 file_attributes = 0775;
2261                 create_options = FILE_DIRECTORY_FILE;
2262         }
2263
2264         status = make_smb2_posix_create_ctx(
2265                 talloc_tos(), &posx, file_attributes);
2266         if (!NT_STATUS_IS_OK(status)) {
2267                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
2268                             nt_errstr(status));
2269                 goto done;
2270         }
2271
2272         status = SMB_VFS_CREATE_FILE(
2273                 conn,           /* conn */
2274                 req,            /* req */
2275                 NULL,           /* dirfsp */
2276                 smb_fname,      /* fname */
2277                 access_mask,    /* access_mask */
2278                 share_access,   /* share_access */
2279                 create_disposition,/* create_disposition*/
2280                 create_options, /* create_options */
2281                 file_attributes,/* file_attributes */
2282                 oplock,         /* oplock_request */
2283                 NULL,           /* lease */
2284                 0,              /* allocation_size */
2285                 0,              /* private_flags */
2286                 NULL,           /* sd */
2287                 NULL,           /* ea_list */
2288                 ret_fsp,        /* result */
2289                 NULL,           /* pinfo */
2290                 posx,           /* in_context */
2291                 NULL);          /* out_context */
2292
2293 done:
2294         TALLOC_FREE(posx);
2295         return status;
2296 }
2297
2298 /****************************************************************************
2299  Utility function to count the number of entries in a POSIX acl.
2300 ****************************************************************************/
2301
2302 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2303 {
2304         unsigned int ace_count = 0;
2305         int entry_id = SMB_ACL_FIRST_ENTRY;
2306         SMB_ACL_ENTRY_T entry;
2307
2308         while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
2309                 entry_id = SMB_ACL_NEXT_ENTRY;
2310                 ace_count++;
2311         }
2312         return ace_count;
2313 }
2314
2315 /****************************************************************************
2316  Utility function to marshall a POSIX acl into wire format.
2317 ****************************************************************************/
2318
2319 static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2320 {
2321         int entry_id = SMB_ACL_FIRST_ENTRY;
2322         SMB_ACL_ENTRY_T entry;
2323
2324         while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
2325                 SMB_ACL_TAG_T tagtype;
2326                 SMB_ACL_PERMSET_T permset;
2327                 unsigned char perms = 0;
2328                 unsigned int own_grp;
2329
2330                 entry_id = SMB_ACL_NEXT_ENTRY;
2331
2332                 if (sys_acl_get_tag_type(entry, &tagtype) == -1) {
2333                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2334                         return False;
2335                 }
2336
2337                 if (sys_acl_get_permset(entry, &permset) == -1) {
2338                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2339                         return False;
2340                 }
2341
2342                 perms |= (sys_acl_get_perm(permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2343                 perms |= (sys_acl_get_perm(permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2344                 perms |= (sys_acl_get_perm(permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2345
2346                 SCVAL(pdata,1,perms);
2347
2348                 switch (tagtype) {
2349                         case SMB_ACL_USER_OBJ:
2350                                 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2351                                 own_grp = (unsigned int)pst->st_ex_uid;
2352                                 SIVAL(pdata,2,own_grp);
2353                                 SIVAL(pdata,6,0);
2354                                 break;
2355                         case SMB_ACL_USER:
2356                                 {
2357                                         uid_t *puid = (uid_t *)sys_acl_get_qualifier(entry);
2358                                         if (!puid) {
2359                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2360                                                 return False;
2361                                         }
2362                                         own_grp = (unsigned int)*puid;
2363                                         SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2364                                         SIVAL(pdata,2,own_grp);
2365                                         SIVAL(pdata,6,0);
2366                                         break;
2367                                 }
2368                         case SMB_ACL_GROUP_OBJ:
2369                                 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2370                                 own_grp = (unsigned int)pst->st_ex_gid;
2371                                 SIVAL(pdata,2,own_grp);
2372                                 SIVAL(pdata,6,0);
2373                                 break;
2374                         case SMB_ACL_GROUP:
2375                                 {
2376                                         gid_t *pgid= (gid_t *)sys_acl_get_qualifier(entry);
2377                                         if (!pgid) {
2378                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2379                                                 return False;
2380                                         }
2381                                         own_grp = (unsigned int)*pgid;
2382                                         SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2383                                         SIVAL(pdata,2,own_grp);
2384                                         SIVAL(pdata,6,0);
2385                                         break;
2386                                 }
2387                         case SMB_ACL_MASK:
2388                                 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2389                                 SIVAL(pdata,2,0xFFFFFFFF);
2390                                 SIVAL(pdata,6,0xFFFFFFFF);
2391                                 break;
2392                         case SMB_ACL_OTHER:
2393                                 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2394                                 SIVAL(pdata,2,0xFFFFFFFF);
2395                                 SIVAL(pdata,6,0xFFFFFFFF);
2396                                 break;
2397                         default:
2398                                 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2399                                 return False;
2400                 }
2401                 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2402         }
2403
2404         return True;
2405 }
2406 #endif
2407
2408 static NTSTATUS smb_q_posix_acl(
2409         struct connection_struct *conn,
2410         struct smb_request *req,
2411         struct smb_filename *smb_fname,
2412         struct files_struct *fsp,
2413         char **ppdata,
2414         int *ptotal_data)
2415 {
2416 #if !defined(HAVE_POSIX_ACLS)
2417         return NT_STATUS_INVALID_LEVEL;
2418 #else
2419         char *pdata = NULL;
2420         SMB_ACL_T file_acl = NULL;
2421         SMB_ACL_T def_acl = NULL;
2422         uint16_t num_file_acls = 0;
2423         uint16_t num_def_acls = 0;
2424         unsigned int size_needed = 0;
2425         NTSTATUS status;
2426         bool ok;
2427         bool close_fsp = false;
2428
2429         /*
2430          * Ensure we always operate on a file descriptor, not just
2431          * the filename.
2432          */
2433         if (fsp == NULL || !fsp->fsp_flags.is_fsa) {
2434                 uint32_t access_mask = SEC_STD_READ_CONTROL|
2435                                         FILE_READ_ATTRIBUTES|
2436                                         FILE_WRITE_ATTRIBUTES;
2437
2438                 status = get_posix_fsp(conn,
2439                                         req,
2440                                         smb_fname,
2441                                         access_mask,
2442                                         &fsp);
2443
2444                 if (!NT_STATUS_IS_OK(status)) {
2445                         goto out;
2446                 }
2447                 close_fsp = true;
2448         }
2449
2450         SMB_ASSERT(fsp != NULL);
2451
2452         status = refuse_symlink_fsp(fsp);
2453         if (!NT_STATUS_IS_OK(status)) {
2454                 goto out;
2455         }
2456
2457         file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, SMB_ACL_TYPE_ACCESS,
2458                                         talloc_tos());
2459
2460         if (file_acl == NULL && no_acl_syscall_error(errno)) {
2461                 DBG_INFO("ACLs not implemented on "
2462                         "filesystem containing %s\n",
2463                         fsp_str_dbg(fsp));
2464                 status = NT_STATUS_NOT_IMPLEMENTED;
2465                 goto out;
2466         }
2467
2468         if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
2469                 /*
2470                  * We can only have default POSIX ACLs on
2471                  * directories.
2472                  */
2473                 if (!fsp->fsp_flags.is_directory) {
2474                         DBG_INFO("Non-directory open %s\n",
2475                                 fsp_str_dbg(fsp));
2476                         status = NT_STATUS_INVALID_HANDLE;
2477                         goto out;
2478                 }
2479                 def_acl = SMB_VFS_SYS_ACL_GET_FD(fsp,
2480                                         SMB_ACL_TYPE_DEFAULT,
2481                                         talloc_tos());
2482                 def_acl = free_empty_sys_acl(conn, def_acl);
2483         }
2484
2485         num_file_acls = count_acl_entries(conn, file_acl);
2486         num_def_acls = count_acl_entries(conn, def_acl);
2487
2488         /* Wrap checks. */
2489         if (num_file_acls + num_def_acls < num_file_acls) {
2490                 status = NT_STATUS_INVALID_PARAMETER;
2491                 goto out;
2492         }
2493
2494         size_needed = num_file_acls + num_def_acls;
2495
2496         /*
2497          * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
2498          * than UINT_MAX, so check by division.
2499          */
2500         if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
2501                 status = NT_STATUS_INVALID_PARAMETER;
2502                 goto out;
2503         }
2504
2505         size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
2506         if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
2507                 status = NT_STATUS_INVALID_PARAMETER;
2508                 goto out;
2509         }
2510         size_needed += SMB_POSIX_ACL_HEADER_SIZE;
2511
2512         *ppdata = SMB_REALLOC(*ppdata, size_needed);
2513         if (*ppdata == NULL) {
2514                 status = NT_STATUS_NO_MEMORY;
2515                 goto out;
2516         }
2517         pdata = *ppdata;
2518
2519         SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
2520         SSVAL(pdata,2,num_file_acls);
2521         SSVAL(pdata,4,num_def_acls);
2522         pdata += SMB_POSIX_ACL_HEADER_SIZE;
2523
2524         ok = marshall_posix_acl(conn,
2525                         pdata,
2526                         &fsp->fsp_name->st,
2527                         file_acl);
2528         if (!ok) {
2529                 status = NT_STATUS_INTERNAL_ERROR;
2530                 goto out;
2531         }
2532         pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
2533
2534         ok = marshall_posix_acl(conn,
2535                         pdata,
2536                         &fsp->fsp_name->st,
2537                         def_acl);
2538         if (!ok) {
2539                 status = NT_STATUS_INTERNAL_ERROR;
2540                 goto out;
2541         }
2542
2543         *ptotal_data = size_needed;
2544         status = NT_STATUS_OK;
2545
2546   out:
2547
2548         if (close_fsp) {
2549                 /*
2550                  * Ensure the stat struct in smb_fname is up to
2551                  * date. Structure copy.
2552                  */
2553                 smb_fname->st = fsp->fsp_name->st;
2554                 (void)close_file_free(req, &fsp, NORMAL_CLOSE);
2555         }
2556
2557         TALLOC_FREE(file_acl);
2558         TALLOC_FREE(def_acl);
2559         return status;
2560 #endif
2561 }
2562
2563 static NTSTATUS smb_q_posix_symlink(
2564         struct connection_struct *conn,
2565         struct smb_request *req,
2566         struct smb_filename *smb_fname,
2567         char **ppdata,
2568         int *ptotal_data)
2569 {
2570         char buffer[PATH_MAX+1];
2571         size_t needed, len;
2572         int link_len;
2573         char *pdata = NULL;
2574         struct smb_filename *parent_fname = NULL;
2575         struct smb_filename *base_name = NULL;
2576         NTSTATUS status;
2577
2578         DBG_DEBUG("SMB_QUERY_FILE_UNIX_LINK for file %s\n",
2579                   smb_fname_str_dbg(smb_fname));
2580
2581         if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
2582                 return NT_STATUS_DOS(ERRSRV, ERRbadlink);
2583         }
2584
2585         status = parent_pathref(
2586                 talloc_tos(),
2587                 conn->cwd_fsp,
2588                 smb_fname,
2589                 &parent_fname,
2590                 &base_name);
2591
2592         if (!NT_STATUS_IS_OK(status)) {
2593                 DBG_DEBUG("parent_pathref failed: %s\n", nt_errstr(status));
2594                 return status;
2595         }
2596
2597         link_len = SMB_VFS_READLINKAT(
2598                 conn,
2599                 parent_fname->fsp,
2600                 base_name,
2601                 buffer,
2602                 sizeof(buffer)-1);
2603         TALLOC_FREE(parent_fname);
2604
2605         if (link_len == -1) {
2606                 status = map_nt_error_from_unix(errno);
2607                 DBG_DEBUG("READLINKAT failed: %s\n", nt_errstr(status));
2608                 return status;
2609         }
2610         if (link_len >= sizeof(buffer)) {
2611                 return NT_STATUS_INTERNAL_ERROR;
2612         }
2613         buffer[link_len] = 0;
2614
2615         needed = (link_len+1)*2;
2616
2617         *ppdata = SMB_REALLOC(*ppdata, needed);
2618         if (*ppdata == NULL) {
2619                 return NT_STATUS_NO_MEMORY;
2620         }
2621         pdata = *ppdata;
2622
2623         status = srvstr_push(
2624                 pdata,
2625                 req->flags2,
2626                 pdata,
2627                 buffer,
2628                 needed,
2629                 STR_TERMINATE,
2630                 &len);
2631         if (!NT_STATUS_IS_OK(status)) {
2632                 return status;
2633         }
2634         *ptotal_data = len;
2635
2636         return NT_STATUS_OK;
2637 }
2638
2639 static void call_trans2qpathinfo(
2640         connection_struct *conn,
2641         struct smb_request *req,
2642         char **pparams,
2643         int total_params,
2644         char **ppdata,
2645         int total_data,
2646         unsigned int max_data_bytes)
2647 {
2648         char *params = *pparams;
2649         uint16_t info_level;
2650         struct smb_filename *smb_fname = NULL;
2651         bool delete_pending = False;
2652         struct timespec write_time_ts = { .tv_sec = 0, };
2653         struct files_struct *dirfsp = NULL;
2654         files_struct *fsp = NULL;
2655         struct file_id fileid;
2656         uint32_t name_hash;
2657         char *fname = NULL;
2658         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
2659         NTTIME twrp = 0;
2660         bool info_level_handled;
2661         NTSTATUS status = NT_STATUS_OK;
2662         int ret;
2663
2664         if (!params) {
2665                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2666                 return;
2667         }
2668
2669
2670         /* qpathinfo */
2671         if (total_params < 7) {
2672                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2673                 return;
2674         }
2675
2676         info_level = SVAL(params,0);
2677
2678         DBG_NOTICE("TRANSACT2_QPATHINFO: level = %d\n", info_level);
2679
2680         if (INFO_LEVEL_IS_UNIX(info_level)) {
2681                 if (!lp_smb1_unix_extensions()) {
2682                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2683                         return;
2684                 }
2685                 if (!req->posix_pathnames) {
2686                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2687                         return;
2688                 }
2689         }
2690
2691         if (req->posix_pathnames) {
2692                 srvstr_get_path_posix(req,
2693                                       params,
2694                                       req->flags2,
2695                                       &fname,
2696                                       &params[6],
2697                                       total_params - 6,
2698                                       STR_TERMINATE,
2699                                       &status);
2700         } else {
2701                 srvstr_get_path(req,
2702                                 params,
2703                                 req->flags2,
2704                                 &fname,
2705                                 &params[6],
2706                                 total_params - 6,
2707                                 STR_TERMINATE,
2708                                 &status);
2709         }
2710         if (!NT_STATUS_IS_OK(status)) {
2711                 reply_nterror(req, status);
2712                 return;
2713         }
2714
2715         if (ucf_flags & UCF_GMT_PATHNAME) {
2716                 extract_snapshot_token(fname, &twrp);
2717         }
2718         status = smb1_strip_dfs_path(req, &ucf_flags, &fname);
2719         if (!NT_STATUS_IS_OK(status)) {
2720                 reply_nterror(req, status);
2721                 return;
2722         }
2723         status = filename_convert_dirfsp(req,
2724                                          conn,
2725                                          fname,
2726                                          ucf_flags,
2727                                          twrp,
2728                                          &dirfsp,
2729                                          &smb_fname);
2730         if (!NT_STATUS_IS_OK(status)) {
2731                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2732                         reply_botherror(req,
2733                                         NT_STATUS_PATH_NOT_COVERED,
2734                                         ERRSRV, ERRbadpath);
2735                         return;
2736                 }
2737                 reply_nterror(req, status);
2738                 return;
2739         }
2740
2741         /*
2742          * qpathinfo must operate on an existing file, so we
2743          * can exit early if filename_convert_dirfsp() returned the
2744          * "new file" NT_STATUS_OK, !VALID_STAT case.
2745          */
2746
2747         if (!VALID_STAT(smb_fname->st)) {
2748                 reply_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2749                 return;
2750         }
2751
2752         /*
2753          * smb_fname->fsp may be NULL if smb_fname points at a symlink
2754          * and we're in POSIX context, so be careful when using fsp
2755          * below, it can still be NULL.
2756          */
2757         fsp = smb_fname->fsp;
2758
2759         /* If this is a stream, check if there is a delete_pending. */
2760         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2761             && is_ntfs_stream_smb_fname(smb_fname)) {
2762                 struct smb_filename *smb_fname_base;
2763
2764                 /* Create an smb_filename with stream_name == NULL. */
2765                 smb_fname_base = synthetic_smb_fname(
2766                         talloc_tos(),
2767                         smb_fname->base_name,
2768                         NULL,
2769                         NULL,
2770                         smb_fname->twrp,
2771                         smb_fname->flags);
2772                 if (smb_fname_base == NULL) {
2773                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2774                         return;
2775                 }
2776
2777                 ret = vfs_stat(conn, smb_fname_base);
2778                 if (ret != 0) {
2779                         DBG_NOTICE("vfs_stat of %s failed "
2780                                    "(%s)\n",
2781                                    smb_fname_str_dbg(smb_fname_base),
2782                                    strerror(errno));
2783                         TALLOC_FREE(smb_fname_base);
2784                         reply_nterror(req,
2785                                       map_nt_error_from_unix(errno));
2786                         return;
2787                 }
2788
2789                 status = file_name_hash(conn,
2790                                         smb_fname_str_dbg(smb_fname_base),
2791                                         &name_hash);
2792                 if (!NT_STATUS_IS_OK(status)) {
2793                         TALLOC_FREE(smb_fname_base);
2794                         reply_nterror(req, status);
2795                         return;
2796                 }
2797
2798                 fileid = vfs_file_id_from_sbuf(conn,
2799                                                &smb_fname_base->st);
2800                 TALLOC_FREE(smb_fname_base);
2801                 get_file_infos(fileid, name_hash, &delete_pending, NULL);
2802                 if (delete_pending) {
2803                         reply_nterror(req, NT_STATUS_DELETE_PENDING);
2804                         return;
2805                 }
2806         }
2807
2808         status = file_name_hash(conn,
2809                                 smb_fname_str_dbg(smb_fname),
2810                                 &name_hash);
2811         if (!NT_STATUS_IS_OK(status)) {
2812                 reply_nterror(req, status);
2813                 return;
2814         }
2815
2816         if (fsp_getinfo_ask_sharemode(fsp)) {
2817                 fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
2818                 get_file_infos(fileid, name_hash, &delete_pending,
2819                                &write_time_ts);
2820         }
2821
2822         if (delete_pending) {
2823                 reply_nterror(req, NT_STATUS_DELETE_PENDING);
2824                 return;
2825         }
2826
2827         info_level_handled = true; /* Untouched in switch cases below */
2828
2829         switch (info_level) {
2830
2831         default:
2832                 info_level_handled = false;
2833                 break;
2834
2835         case SMB_QUERY_FILE_UNIX_BASIC:
2836                 status = smb_q_unix_basic(
2837                         conn,
2838                         req,
2839                         smb_fname,
2840                         smb_fname->fsp,
2841                         ppdata,
2842                         &total_data);
2843                 break;
2844
2845         case SMB_QUERY_FILE_UNIX_INFO2:
2846                 status = smb_q_unix_info2(
2847                         conn,
2848                         req,
2849                         smb_fname,
2850                         smb_fname->fsp,
2851                         ppdata,
2852                         &total_data);
2853                 break;
2854
2855         case SMB_QUERY_POSIX_ACL:
2856                 status = smb_q_posix_acl(
2857                         conn,
2858                         req,
2859                         smb_fname,
2860                         smb_fname->fsp,
2861                         ppdata,
2862                         &total_data);
2863                 break;
2864
2865         case SMB_QUERY_FILE_UNIX_LINK:
2866                 status = smb_q_posix_symlink(
2867                         conn,
2868                         req,
2869                         smb_fname,
2870                         ppdata,
2871                         &total_data);
2872                 break;
2873         }
2874
2875         if (info_level_handled) {
2876                 handle_trans2qfilepathinfo_result(
2877                         conn,
2878                         req,
2879                         info_level,
2880                         status,
2881                         *ppdata,
2882                         total_data,
2883                         total_data,
2884                         max_data_bytes);
2885                 return;
2886         }
2887
2888         call_trans2qfilepathinfo(
2889                 conn,
2890                 req,
2891                 TRANSACT2_QPATHINFO,
2892                 info_level,
2893                 smb_fname,
2894                 fsp,
2895                 false,
2896                 write_time_ts,
2897                 pparams,
2898                 total_params,
2899                 ppdata,
2900                 total_data,
2901                 max_data_bytes);
2902 }
2903
2904 static NTSTATUS smb_q_posix_lock(
2905         struct connection_struct *conn,
2906         struct smb_request *req,
2907         struct files_struct *fsp,
2908         char **ppdata,
2909         int *ptotal_data)
2910 {
2911         char *pdata = *ppdata;
2912         int total_data = *ptotal_data;
2913         uint64_t count;
2914         uint64_t offset;
2915         uint64_t smblctx;
2916         enum brl_type lock_type;
2917         NTSTATUS status;
2918
2919         if (fsp->fsp_flags.is_pathref || (fsp_get_io_fd(fsp) == -1)) {
2920                 return NT_STATUS_INVALID_HANDLE;
2921         }
2922
2923         if (total_data != POSIX_LOCK_DATA_SIZE) {
2924                 return NT_STATUS_INVALID_PARAMETER;
2925         }
2926
2927         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
2928         case POSIX_LOCK_TYPE_READ:
2929                 lock_type = READ_LOCK;
2930                 break;
2931         case POSIX_LOCK_TYPE_WRITE:
2932                 lock_type = WRITE_LOCK;
2933                 break;
2934         case POSIX_LOCK_TYPE_UNLOCK:
2935         default:
2936                 /* There's no point in asking for an unlock... */
2937                 return NT_STATUS_INVALID_PARAMETER;
2938         }
2939
2940         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
2941         offset = BVAL(pdata,POSIX_LOCK_START_OFFSET);
2942         count = BVAL(pdata,POSIX_LOCK_LEN_OFFSET);
2943
2944         status = query_lock(
2945                 fsp,
2946                 &smblctx,
2947                 &count,
2948                 &offset,
2949                 &lock_type,
2950                 POSIX_LOCK);
2951
2952         if (NT_STATUS_IS_OK(status)) {
2953                 /*
2954                  * For success we just return a copy of what we sent
2955                  * with the lock type set to POSIX_LOCK_TYPE_UNLOCK.
2956                  */
2957                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
2958                 return NT_STATUS_OK;
2959         }
2960
2961         if (!ERROR_WAS_LOCK_DENIED(status)) {
2962                 DBG_DEBUG("query_lock() failed: %s\n", nt_errstr(status));
2963                 return status;
2964         }
2965
2966         /*
2967          * Here we need to report who has it locked.
2968          */
2969
2970         SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
2971         SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
2972         SIVAL(pdata, POSIX_LOCK_PID_OFFSET, (uint32_t)smblctx);
2973         SBVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
2974         SBVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
2975
2976         return NT_STATUS_OK;
2977 }
2978
2979 static void call_trans2qfileinfo(
2980         connection_struct *conn,
2981         struct smb_request *req,
2982         char **pparams,
2983         int total_params,
2984         char **ppdata,
2985         int total_data,
2986         unsigned int max_data_bytes)
2987 {
2988         char *params = *pparams;
2989         uint16_t info_level;
2990         struct smb_filename *smb_fname = NULL;
2991         bool delete_pending = False;
2992         struct timespec write_time_ts = { .tv_sec = 0, };
2993         files_struct *fsp = NULL;
2994         struct file_id fileid;
2995         bool info_level_handled;
2996         NTSTATUS status = NT_STATUS_OK;
2997         int ret;
2998
2999         if (params == NULL) {
3000                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3001                 return;
3002         }
3003
3004         if (total_params < 4) {
3005                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3006                 return;
3007         }
3008
3009         fsp = file_fsp(req, SVAL(params,0));
3010         info_level = SVAL(params,2);
3011
3012         if (IS_IPC(conn)) {
3013                 call_trans2qpipeinfo(
3014                         conn,
3015                         req,
3016                         fsp,
3017                         info_level,
3018                         TRANSACT2_QFILEINFO,
3019                         pparams,
3020                         total_params,
3021                         ppdata,
3022                         total_data,
3023                         max_data_bytes);
3024                 return;
3025         }
3026
3027         DBG_NOTICE("TRANSACT2_QFILEINFO: level = %d\n", info_level);
3028
3029         if (INFO_LEVEL_IS_UNIX(info_level)) {
3030                 if (!lp_smb1_unix_extensions()) {
3031                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3032                         return;
3033                 }
3034                 if (!req->posix_pathnames) {
3035                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3036                         return;
3037                 }
3038         }
3039
3040         /* Initial check for valid fsp ptr. */
3041         if (!check_fsp_open(conn, req, fsp)) {
3042                 return;
3043         }
3044
3045         smb_fname = fsp->fsp_name;
3046
3047         if(fsp->fake_file_handle) {
3048                 /*
3049                  * This is actually for the QUOTA_FAKE_FILE --metze
3050                  */
3051
3052                 /* We know this name is ok, it's already passed the checks. */
3053
3054         } else if(fsp_get_pathref_fd(fsp) == -1) {
3055                 /*
3056                  * This is actually a QFILEINFO on a directory
3057                  * handle (returned from an NT SMB). NT5.0 seems
3058                  * to do this call. JRA.
3059                  */
3060                 ret = vfs_stat(conn, smb_fname);
3061                 if (ret != 0) {
3062                         DBG_NOTICE("vfs_stat of %s failed (%s)\n",
3063                                    smb_fname_str_dbg(smb_fname),
3064                                    strerror(errno));
3065                         reply_nterror(req,
3066                                       map_nt_error_from_unix(errno));
3067                         return;
3068                 }
3069
3070                 if (fsp_getinfo_ask_sharemode(fsp)) {
3071                         fileid = vfs_file_id_from_sbuf(
3072                                 conn, &smb_fname->st);
3073                         get_file_infos(fileid, fsp->name_hash,
3074                                        &delete_pending,
3075                                        &write_time_ts);
3076                 }
3077         } else {
3078                 /*
3079                  * Original code - this is an open file.
3080                  */
3081                 status = vfs_stat_fsp(fsp);
3082                 if (!NT_STATUS_IS_OK(status)) {
3083                         DEBUG(3, ("fstat of %s failed (%s)\n",
3084                                   fsp_fnum_dbg(fsp), nt_errstr(status)));
3085                         reply_nterror(req, status);
3086                         return;
3087                 }
3088                 if (fsp_getinfo_ask_sharemode(fsp)) {
3089                         fileid = vfs_file_id_from_sbuf(
3090                                 conn, &smb_fname->st);
3091                         get_file_infos(fileid, fsp->name_hash,
3092                                        &delete_pending,
3093                                        &write_time_ts);
3094                 }
3095         }
3096
3097         info_level_handled = true; /* Untouched in switch cases below */
3098
3099         switch (info_level) {
3100
3101         default:
3102                 info_level_handled = false;
3103                 break;
3104
3105         case SMB_QUERY_POSIX_LOCK:
3106                 status = smb_q_posix_lock(conn, req, fsp, ppdata, &total_data);
3107                 break;
3108
3109         case SMB_QUERY_FILE_UNIX_BASIC:
3110                 status = smb_q_unix_basic(
3111                         conn, req, fsp->fsp_name, fsp, ppdata, &total_data);
3112                 break;
3113
3114         case SMB_QUERY_FILE_UNIX_INFO2:
3115                 status = smb_q_unix_info2(
3116                         conn, req, fsp->fsp_name, fsp, ppdata, &total_data);
3117                 break;
3118
3119         case SMB_QUERY_POSIX_ACL:
3120                 status = smb_q_posix_acl(
3121                         conn, req, fsp->fsp_name, fsp, ppdata, &total_data);
3122                 break;
3123         }
3124
3125         if (info_level_handled) {
3126                 handle_trans2qfilepathinfo_result(
3127                         conn,
3128                         req,
3129                         info_level,
3130                         status,
3131                         *ppdata,
3132                         total_data,
3133                         total_data,
3134                         max_data_bytes);
3135                 return;
3136         }
3137
3138         call_trans2qfilepathinfo(
3139                 conn,
3140                 req,
3141                 TRANSACT2_QFILEINFO,
3142                 info_level,
3143                 smb_fname,
3144                 fsp,
3145                 delete_pending,
3146                 write_time_ts,
3147                 pparams,
3148                 total_params,
3149                 ppdata,
3150                 total_data,
3151                 max_data_bytes);
3152 }
3153
3154 static void handle_trans2setfilepathinfo_result(
3155         connection_struct *conn,
3156         struct smb_request *req,
3157         uint16_t info_level,
3158         NTSTATUS status,
3159         char *pdata,
3160         int data_return_size,
3161         unsigned int max_data_bytes)
3162 {
3163         char params[2] = { 0, 0, };
3164
3165         if (NT_STATUS_IS_OK(status)) {
3166                 send_trans2_replies(
3167                         conn,
3168                         req,
3169                         NT_STATUS_OK,
3170                         params,
3171                         2,
3172                         pdata,
3173                         data_return_size,
3174                         max_data_bytes);
3175                 return;
3176         }
3177
3178         if (open_was_deferred(req->xconn, req->mid)) {
3179                 /* We have re-scheduled this call. */
3180                 return;
3181         }
3182
3183         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3184                 bool ok = defer_smb1_sharing_violation(req);
3185                 if (ok) {
3186                         return;
3187                 }
3188         }
3189
3190         if (NT_STATUS_EQUAL(status, NT_STATUS_EVENT_PENDING)) {
3191                 /* We have re-scheduled this call. */
3192                 return;
3193         }
3194
3195         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
3196                 reply_botherror(
3197                         req,
3198                         NT_STATUS_PATH_NOT_COVERED,
3199                         ERRSRV,
3200                         ERRbadpath);
3201                 return;
3202         }
3203
3204         if (info_level == SMB_POSIX_PATH_OPEN) {
3205                 reply_openerror(req, status);
3206                 return;
3207         }
3208
3209         if (NT_STATUS_EQUAL(status, STATUS_INVALID_EA_NAME)) {
3210                 /*
3211                  * Invalid EA name needs to return 2 param bytes,
3212                  * not a zero-length error packet.
3213                  */
3214
3215                 send_trans2_replies(
3216                         conn,
3217                         req,
3218                         status,
3219                         params,
3220                         2,
3221                         NULL,
3222                         0,
3223                         max_data_bytes);
3224                 return;
3225         }
3226
3227         reply_nterror(req, status);
3228 }
3229
3230 /****************************************************************************
3231  Create a directory with POSIX semantics.
3232 ****************************************************************************/
3233
3234 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
3235                                 struct smb_request *req,
3236                                 char **ppdata,
3237                                 int total_data,
3238                                 struct smb_filename *smb_fname,
3239                                 int *pdata_return_size)
3240 {
3241         NTSTATUS status = NT_STATUS_OK;
3242         uint32_t raw_unixmode = 0;
3243         mode_t unixmode = (mode_t)0;
3244         files_struct *fsp = NULL;
3245         uint16_t info_level_return = 0;
3246         int info;
3247         char *pdata = *ppdata;
3248         struct smb2_create_blobs *posx = NULL;
3249
3250         if (total_data < 18) {
3251                 return NT_STATUS_INVALID_PARAMETER;
3252         }
3253
3254         raw_unixmode = IVAL(pdata,8);
3255         /* Next 4 bytes are not yet defined. */
3256
3257         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
3258                                       PERM_NEW_DIR, &unixmode);
3259         if (!NT_STATUS_IS_OK(status)) {
3260                 return status;
3261         }
3262
3263         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode);
3264         if (!NT_STATUS_IS_OK(status)) {
3265                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
3266                             nt_errstr(status));
3267                 return status;
3268         }
3269
3270         DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
3271                   smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
3272
3273         status = SMB_VFS_CREATE_FILE(
3274                 conn,                                   /* conn */
3275                 req,                                    /* req */
3276                 NULL,                                   /* dirfsp */
3277                 smb_fname,                              /* fname */
3278                 FILE_READ_ATTRIBUTES,                   /* access_mask */
3279                 FILE_SHARE_NONE,                        /* share_access */
3280                 FILE_CREATE,                            /* create_disposition*/
3281                 FILE_DIRECTORY_FILE,                    /* create_options */
3282                 0,                                      /* file_attributes */
3283                 0,                                      /* oplock_request */
3284                 NULL,                                   /* lease */
3285                 0,                                      /* allocation_size */
3286                 0,                                      /* private_flags */
3287                 NULL,                                   /* sd */
3288                 NULL,                                   /* ea_list */
3289                 &fsp,                                   /* result */
3290                 &info,                                  /* pinfo */
3291                 posx,                                   /* in_context_blobs */
3292                 NULL);                                  /* out_context_blobs */
3293
3294         TALLOC_FREE(posx);
3295
3296         if (NT_STATUS_IS_OK(status)) {
3297                 close_file_free(req, &fsp, NORMAL_CLOSE);
3298         }
3299
3300         info_level_return = SVAL(pdata,16);
3301
3302         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
3303                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
3304         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
3305                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
3306         } else {
3307                 *pdata_return_size = 12;
3308         }
3309
3310         /* Realloc the data size */
3311         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
3312         if (*ppdata == NULL) {
3313                 *pdata_return_size = 0;
3314                 return NT_STATUS_NO_MEMORY;
3315         }
3316         pdata = *ppdata;
3317
3318         SSVAL(pdata,0,NO_OPLOCK_RETURN);
3319         SSVAL(pdata,2,0); /* No fnum. */
3320         SIVAL(pdata,4,info); /* Was directory created. */
3321
3322         switch (info_level_return) {
3323                 case SMB_QUERY_FILE_UNIX_BASIC:
3324                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
3325                         SSVAL(pdata,10,0); /* Padding. */
3326                         store_file_unix_basic(conn, pdata + 12, fsp,
3327                                               &smb_fname->st);
3328                         break;
3329                 case SMB_QUERY_FILE_UNIX_INFO2:
3330                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
3331                         SSVAL(pdata,10,0); /* Padding. */
3332                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
3333                                                     &smb_fname->st);
3334                         break;
3335                 default:
3336                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
3337                         SSVAL(pdata,10,0); /* Padding. */
3338                         break;
3339         }
3340
3341         return status;
3342 }
3343
3344 /****************************************************************************
3345  Open/Create a file with POSIX semantics.
3346 ****************************************************************************/
3347
3348 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
3349 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
3350
3351 static NTSTATUS smb_posix_open(connection_struct *conn,
3352                                struct smb_request *req,
3353                                 char **ppdata,
3354                                 int total_data,
3355                                 struct smb_filename *smb_fname,
3356                                 int *pdata_return_size)
3357 {
3358         bool extended_oplock_granted = False;
3359         char *pdata = *ppdata;
3360         uint32_t flags = 0;
3361         uint32_t wire_open_mode = 0;
3362         uint32_t raw_unixmode = 0;
3363         uint32_t attributes = 0;
3364         uint32_t create_disp = 0;
3365         uint32_t access_mask = 0;
3366         uint32_t create_options = FILE_NON_DIRECTORY_FILE;
3367         NTSTATUS status = NT_STATUS_OK;
3368         mode_t unixmode = (mode_t)0;
3369         files_struct *fsp = NULL;
3370         int oplock_request = 0;
3371         int info = 0;
3372         uint16_t info_level_return = 0;
3373         struct smb2_create_blobs *posx = NULL;
3374
3375         if (total_data < 18) {
3376                 return NT_STATUS_INVALID_PARAMETER;
3377         }
3378
3379         flags = IVAL(pdata,0);
3380         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
3381         if (oplock_request) {
3382                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
3383         }
3384
3385         wire_open_mode = IVAL(pdata,4);
3386
3387         if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
3388                 return smb_posix_mkdir(conn, req,
3389                                         ppdata,
3390                                         total_data,
3391                                         smb_fname,
3392                                         pdata_return_size);
3393         }
3394
3395         switch (wire_open_mode & SMB_ACCMODE) {
3396                 case SMB_O_RDONLY:
3397                         access_mask = SMB_O_RDONLY_MAPPING;
3398                         break;
3399                 case SMB_O_WRONLY:
3400                         access_mask = SMB_O_WRONLY_MAPPING;
3401                         break;
3402                 case SMB_O_RDWR:
3403                         access_mask = (SMB_O_RDONLY_MAPPING|
3404                                         SMB_O_WRONLY_MAPPING);
3405                         break;
3406                 default:
3407                         DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
3408                                 (unsigned int)wire_open_mode ));
3409                         return NT_STATUS_INVALID_PARAMETER;
3410         }
3411
3412         wire_open_mode &= ~SMB_ACCMODE;
3413
3414         /* First take care of O_CREAT|O_EXCL interactions. */
3415         switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
3416                 case (SMB_O_CREAT | SMB_O_EXCL):
3417                         /* File exists fail. File not exist create. */
3418                         create_disp = FILE_CREATE;
3419                         break;
3420                 case SMB_O_CREAT:
3421                         /* File exists open. File not exist create. */
3422                         create_disp = FILE_OPEN_IF;
3423                         break;
3424                 case SMB_O_EXCL:
3425                         /* O_EXCL on its own without O_CREAT is undefined.
3426                            We deliberately ignore it as some versions of
3427                            Linux CIFSFS can send a bare O_EXCL on the
3428                            wire which other filesystems in the kernel
3429                            ignore. See bug 9519 for details. */
3430
3431                         /* Fallthrough. */
3432
3433                 case 0:
3434                         /* File exists open. File not exist fail. */
3435                         create_disp = FILE_OPEN;
3436                         break;
3437                 default:
3438                         DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
3439                                 (unsigned int)wire_open_mode ));
3440                         return NT_STATUS_INVALID_PARAMETER;
3441         }
3442
3443         /* Next factor in the effects of O_TRUNC. */
3444         wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
3445
3446         if (wire_open_mode & SMB_O_TRUNC) {
3447                 switch (create_disp) {
3448                         case FILE_CREATE:
3449                                 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
3450                                 /* Leave create_disp alone as
3451                                    (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
3452                                 */
3453                                 /* File exists fail. File not exist create. */
3454                                 break;
3455                         case FILE_OPEN_IF:
3456                                 /* SMB_O_CREAT | SMB_O_TRUNC */
3457                                 /* File exists overwrite. File not exist create. */
3458                                 create_disp = FILE_OVERWRITE_IF;
3459                                 break;
3460                         case FILE_OPEN:
3461                                 /* SMB_O_TRUNC */
3462                                 /* File exists overwrite. File not exist fail. */
3463                                 create_disp = FILE_OVERWRITE;
3464                                 break;
3465                         default:
3466                                 /* Cannot get here. */
3467                                 smb_panic("smb_posix_open: logic error");
3468                                 return NT_STATUS_INVALID_PARAMETER;
3469                 }
3470         }
3471
3472         raw_unixmode = IVAL(pdata,8);
3473         /* Next 4 bytes are not yet defined. */
3474
3475         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
3476                                       (VALID_STAT(smb_fname->st) ?
3477                                           PERM_EXISTING_FILE : PERM_NEW_FILE),
3478                                       &unixmode);
3479
3480         if (!NT_STATUS_IS_OK(status)) {
3481                 return status;
3482         }
3483
3484         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode);
3485         if (!NT_STATUS_IS_OK(status)) {
3486                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
3487                             nt_errstr(status));
3488                 return status;
3489         }
3490
3491         if (wire_open_mode & SMB_O_SYNC) {
3492                 create_options |= FILE_WRITE_THROUGH;
3493         }
3494         if (wire_open_mode & SMB_O_APPEND) {
3495                 access_mask |= FILE_APPEND_DATA;
3496         }
3497         if (wire_open_mode & SMB_O_DIRECT) {
3498                 attributes |= FILE_FLAG_NO_BUFFERING;
3499         }
3500
3501         if ((wire_open_mode & SMB_O_DIRECTORY) ||
3502                         VALID_STAT_OF_DIR(smb_fname->st)) {
3503                 if (access_mask != SMB_O_RDONLY_MAPPING) {
3504                         return NT_STATUS_FILE_IS_A_DIRECTORY;
3505                 }
3506                 create_options &= ~FILE_NON_DIRECTORY_FILE;
3507                 create_options |= FILE_DIRECTORY_FILE;
3508         }
3509
3510         DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
3511                 smb_fname_str_dbg(smb_fname),
3512                 (unsigned int)wire_open_mode,
3513                 (unsigned int)unixmode ));
3514
3515         status = SMB_VFS_CREATE_FILE(
3516                 conn,                                   /* conn */
3517                 req,                                    /* req */
3518                 NULL,                                   /* dirfsp */
3519                 smb_fname,                              /* fname */
3520                 access_mask,                            /* access_mask */
3521                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
3522                     FILE_SHARE_DELETE),
3523                 create_disp,                            /* create_disposition*/
3524                 create_options,                         /* create_options */
3525                 attributes,                             /* file_attributes */
3526                 oplock_request,                         /* oplock_request */
3527                 NULL,                                   /* lease */
3528                 0,                                      /* allocation_size */
3529                 0,                                      /* private_flags */
3530                 NULL,                                   /* sd */
3531                 NULL,                                   /* ea_list */
3532                 &fsp,                                   /* result */
3533                 &info,                                  /* pinfo */
3534                 posx,                                   /* in_context_blobs */
3535                 NULL);                                  /* out_context_blobs */
3536
3537         TALLOC_FREE(posx);
3538
3539         if (!NT_STATUS_IS_OK(status)) {
3540                 return status;
3541         }
3542
3543         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
3544                 extended_oplock_granted = True;
3545         }
3546
3547         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
3548                 extended_oplock_granted = True;
3549         }
3550
3551         info_level_return = SVAL(pdata,16);
3552
3553         /* Allocate the correct return size. */
3554
3555         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
3556                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
3557         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
3558                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
3559         } else {
3560                 *pdata_return_size = 12;
3561         }
3562
3563         /* Realloc the data size */
3564         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
3565         if (*ppdata == NULL) {
3566                 close_file_free(req, &fsp, ERROR_CLOSE);
3567                 *pdata_return_size = 0;
3568                 return NT_STATUS_NO_MEMORY;
3569         }
3570         pdata = *ppdata;
3571
3572         if (extended_oplock_granted) {
3573                 if (flags & REQUEST_BATCH_OPLOCK) {
3574                         SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
3575                 } else {
3576                         SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
3577                 }
3578         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
3579                 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
3580         } else {
3581                 SSVAL(pdata,0,NO_OPLOCK_RETURN);
3582         }
3583
3584         SSVAL(pdata,2,fsp->fnum);
3585         SIVAL(pdata,4,info); /* Was file created etc. */
3586
3587         switch (info_level_return) {
3588                 case SMB_QUERY_FILE_UNIX_BASIC:
3589                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
3590                         SSVAL(pdata,10,0); /* padding. */
3591                         store_file_unix_basic(conn, pdata + 12, fsp,
3592                                               &smb_fname->st);
3593                         break;
3594                 case SMB_QUERY_FILE_UNIX_INFO2:
3595                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
3596                         SSVAL(pdata,10,0); /* padding. */
3597                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
3598                                                     &smb_fname->st);
3599                         break;
3600                 default:
3601                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
3602                         SSVAL(pdata,10,0); /* padding. */
3603                         break;
3604         }
3605         return NT_STATUS_OK;
3606 }
3607
3608 /****************************************************************************
3609  Delete a file with POSIX semantics.
3610 ****************************************************************************/
3611
3612 struct smb_posix_unlink_state {
3613         struct smb_filename *smb_fname;
3614         struct files_struct *fsp;
3615         NTSTATUS status;
3616 };
3617
3618 static void smb_posix_unlink_locked(struct share_mode_lock *lck,
3619                                     void *private_data)
3620 {
3621         struct smb_posix_unlink_state *state = private_data;
3622         char del = 1;
3623         bool other_nonposix_opens;
3624
3625         other_nonposix_opens = has_other_nonposix_opens(lck, state->fsp);
3626         if (other_nonposix_opens) {
3627                 /* Fail with sharing violation. */
3628                 state->status = NT_STATUS_SHARING_VIOLATION;
3629                 return;
3630         }
3631
3632         /*
3633          * Set the delete on close.
3634          */
3635         state->status = smb_set_file_disposition_info(state->fsp->conn,
3636                                                       &del,
3637                                                       1,
3638                                                       state->fsp,
3639                                                       state->smb_fname);
3640 }
3641
3642 static NTSTATUS smb_posix_unlink(connection_struct *conn,
3643                                  struct smb_request *req,
3644                                 const char *pdata,
3645                                 int total_data,
3646                                 struct smb_filename *smb_fname)
3647 {
3648         struct smb_posix_unlink_state state = {};
3649         NTSTATUS status = NT_STATUS_OK;
3650         files_struct *fsp = NULL;
3651         uint16_t flags = 0;
3652         int info = 0;
3653         int create_options = 0;
3654         struct smb2_create_blobs *posx = NULL;
3655
3656         if (!CAN_WRITE(conn)) {
3657                 return NT_STATUS_DOS(ERRSRV, ERRaccess);
3658         }
3659
3660         if (total_data < 2) {
3661                 return NT_STATUS_INVALID_PARAMETER;
3662         }
3663
3664         flags = SVAL(pdata,0);
3665
3666         if (!VALID_STAT(smb_fname->st)) {
3667                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3668         }
3669
3670         if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
3671                         !VALID_STAT_OF_DIR(smb_fname->st)) {
3672                 return NT_STATUS_NOT_A_DIRECTORY;
3673         }
3674
3675         DEBUG(10,("smb_posix_unlink: %s %s\n",
3676                 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
3677                 smb_fname_str_dbg(smb_fname)));
3678
3679         if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3680                 create_options |= FILE_DIRECTORY_FILE;
3681         }
3682
3683         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777);
3684         if (!NT_STATUS_IS_OK(status)) {
3685                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
3686                             nt_errstr(status));
3687                 return status;
3688         }
3689
3690         status = SMB_VFS_CREATE_FILE(
3691                 conn,                                   /* conn */
3692                 req,                                    /* req */
3693                 NULL,                                   /* dirfsp */
3694                 smb_fname,                              /* fname */
3695                 DELETE_ACCESS,                          /* access_mask */
3696                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
3697                     FILE_SHARE_DELETE),
3698                 FILE_OPEN,                              /* create_disposition*/
3699                 create_options,                         /* create_options */
3700                 0,                                      /* file_attributes */
3701                 0,                                      /* oplock_request */
3702                 NULL,                                   /* lease */
3703                 0,                                      /* allocation_size */
3704                 0,                                      /* private_flags */
3705                 NULL,                                   /* sd */
3706                 NULL,                                   /* ea_list */
3707                 &fsp,                                   /* result */
3708                 &info,                                  /* pinfo */
3709                 posx,                                   /* in_context_blobs */
3710                 NULL);                                  /* out_context_blobs */
3711
3712         TALLOC_FREE(posx);
3713
3714         if (!NT_STATUS_IS_OK(status)) {
3715                 return status;
3716         }
3717
3718         /*
3719          * Don't lie to client. If we can't really delete due to
3720          * non-POSIX opens return SHARING_VIOLATION.
3721          */
3722
3723         state = (struct smb_posix_unlink_state) {
3724                 .smb_fname = smb_fname,
3725                 .fsp = fsp,
3726         };
3727
3728         status = share_mode_do_locked_vfs_allowed(fsp->file_id,
3729                                                   smb_posix_unlink_locked,
3730                                                   &state);
3731         if (!NT_STATUS_IS_OK(status)) {
3732                 DBG_ERR("share_mode_do_locked_vfs_allowed(%s) failed - %s\n",
3733                         fsp_str_dbg(fsp), nt_errstr(status));
3734                 close_file_free(req, &fsp, NORMAL_CLOSE);
3735                 return NT_STATUS_INVALID_PARAMETER;
3736         }
3737
3738         status = state.status;
3739         if (!NT_STATUS_IS_OK(status)) {
3740                 close_file_free(req, &fsp, NORMAL_CLOSE);
3741                 return status;
3742         }
3743         return close_file_free(req, &fsp, NORMAL_CLOSE);
3744 }
3745
3746 /****************************************************************************
3747  Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
3748 ****************************************************************************/
3749
3750 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
3751                                        struct smb_request *req,
3752                                        const char *pdata,
3753                                        int total_data,
3754                                        struct smb_filename *new_smb_fname)
3755 {
3756         char *link_target = NULL;
3757         struct smb_filename target_fname;
3758         TALLOC_CTX *ctx = talloc_tos();
3759         NTSTATUS status;
3760         int ret;
3761         struct smb_filename *parent_fname = NULL;
3762         struct smb_filename *base_name = NULL;
3763
3764         if (!CAN_WRITE(conn)) {
3765                 return NT_STATUS_DOS(ERRSRV, ERRaccess);
3766         }
3767
3768         /* Set a symbolic link. */
3769         /* Don't allow this if follow links is false. */
3770
3771         if (total_data == 0) {
3772                 return NT_STATUS_INVALID_PARAMETER;
3773         }
3774
3775         if (!lp_follow_symlinks(SNUM(conn))) {
3776                 return NT_STATUS_ACCESS_DENIED;
3777         }
3778
3779         srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
3780                     total_data, STR_TERMINATE);
3781
3782         if (!link_target) {
3783                 return NT_STATUS_INVALID_PARAMETER;
3784         }
3785
3786         target_fname = (struct smb_filename) {
3787                 .base_name = link_target,
3788         };
3789
3790         /* Removes @GMT tokens if any */
3791         status = canonicalize_snapshot_path(&target_fname, UCF_GMT_PATHNAME, 0);
3792         if (!NT_STATUS_IS_OK(status)) {
3793                 return status;
3794         }
3795
3796         DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3797                         new_smb_fname->base_name, link_target ));
3798
3799         status = parent_pathref(talloc_tos(),
3800                                 conn->cwd_fsp,
3801                                 new_smb_fname,
3802                                 &parent_fname,
3803                                 &base_name);
3804         if (!NT_STATUS_IS_OK(status)) {
3805                 return status;
3806         }
3807
3808         ret = SMB_VFS_SYMLINKAT(conn,
3809                         &target_fname,
3810                         parent_fname->fsp,
3811                         base_name);
3812         if (ret != 0) {
3813                 TALLOC_FREE(parent_fname);
3814                 return map_nt_error_from_unix(errno);
3815         }
3816
3817         TALLOC_FREE(parent_fname);
3818         return NT_STATUS_OK;
3819 }
3820
3821 /****************************************************************************
3822  Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
3823 ****************************************************************************/
3824
3825 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
3826                                         struct smb_request *req,
3827                                         const char *pdata, int total_data,
3828                                         struct smb_filename *smb_fname_new)
3829 {
3830         char *oldname = NULL;
3831         struct files_struct *src_dirfsp = NULL;
3832         struct smb_filename *smb_fname_old = NULL;
3833         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
3834         NTTIME old_twrp = 0;
3835         TALLOC_CTX *ctx = talloc_tos();
3836         NTSTATUS status = NT_STATUS_OK;
3837
3838         if (!CAN_WRITE(conn)) {
3839                 return NT_STATUS_DOS(ERRSRV, ERRaccess);
3840         }
3841
3842         /* Set a hard link. */
3843         if (total_data == 0) {
3844                 return NT_STATUS_INVALID_PARAMETER;
3845         }
3846
3847         if (req->posix_pathnames) {
3848                 srvstr_get_path_posix(ctx,
3849                         pdata,
3850                         req->flags2,
3851                         &oldname,
3852                         pdata,
3853                         total_data,
3854                         STR_TERMINATE,
3855                         &status);
3856         } else {
3857                 srvstr_get_path(ctx,
3858                         pdata,
3859                         req->flags2,
3860                         &oldname,
3861                         pdata,
3862                         total_data,
3863                         STR_TERMINATE,
3864                         &status);
3865         }
3866         if (!NT_STATUS_IS_OK(status)) {
3867                 return status;
3868         }
3869
3870         DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3871                 smb_fname_str_dbg(smb_fname_new), oldname));
3872
3873         if (ucf_flags & UCF_GMT_PATHNAME) {
3874                 extract_snapshot_token(oldname, &old_twrp);
3875         }
3876         status = smb1_strip_dfs_path(ctx, &ucf_flags, &oldname);
3877         if (!NT_STATUS_IS_OK(status)) {
3878                 return status;
3879         }
3880         status = filename_convert_dirfsp(ctx,
3881                                          conn,
3882                                          oldname,
3883                                          ucf_flags,
3884                                          old_twrp,
3885                                          &src_dirfsp,
3886                                          &smb_fname_old);
3887         if (!NT_STATUS_IS_OK(status)) {
3888                 return status;
3889         }
3890
3891         return hardlink_internals(ctx,
3892                                   conn,
3893                                   req,
3894                                   false,
3895                                   src_dirfsp,
3896                                   smb_fname_old,
3897                                   NULL, /* new_dirfsp */
3898                                   smb_fname_new);
3899 }
3900
3901 /****************************************************************************
3902  Allow a UNIX info mknod.
3903 ****************************************************************************/
3904
3905 static NTSTATUS smb_unix_mknod(connection_struct *conn,
3906                                         const char *pdata,
3907                                         int total_data,
3908                                         const struct smb_filename *smb_fname)
3909 {
3910         uint32_t file_type = IVAL(pdata,56);
3911 #if defined(HAVE_MAKEDEV)
3912         uint32_t dev_major = IVAL(pdata,60);
3913         uint32_t dev_minor = IVAL(pdata,68);
3914 #endif
3915         SMB_DEV_T dev = (SMB_DEV_T)0;
3916         uint32_t raw_unixmode = IVAL(pdata,84);
3917         NTSTATUS status;
3918         mode_t unixmode;
3919         int ret;
3920         struct smb_filename *parent_fname = NULL;
3921         struct smb_filename *base_name = NULL;
3922
3923         if (total_data < 100) {
3924                 return NT_STATUS_INVALID_PARAMETER;
3925         }
3926
3927         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
3928                                       PERM_NEW_FILE, &unixmode);
3929         if (!NT_STATUS_IS_OK(status)) {
3930                 return status;
3931         }
3932
3933 #if defined(HAVE_MAKEDEV)
3934         dev = makedev(dev_major, dev_minor);
3935 #endif
3936
3937         switch (file_type) {
3938                 /* We can't create other objects here. */
3939                 case UNIX_TYPE_FILE:
3940                 case UNIX_TYPE_DIR:
3941                 case UNIX_TYPE_SYMLINK:
3942                         return NT_STATUS_ACCESS_DENIED;
3943 #if defined(S_IFIFO)
3944                 case UNIX_TYPE_FIFO:
3945                         unixmode |= S_IFIFO;
3946                         break;
3947 #endif
3948 #if defined(S_IFSOCK)
3949                 case UNIX_TYPE_SOCKET:
3950                         unixmode |= S_IFSOCK;
3951                         break;
3952 #endif
3953 #if defined(S_IFCHR)
3954                 case UNIX_TYPE_CHARDEV:
3955                         /* This is only allowed for root. */
3956                         if (get_current_uid(conn) != sec_initial_uid()) {
3957                                 return NT_STATUS_ACCESS_DENIED;
3958                         }
3959                         unixmode |= S_IFCHR;
3960                         break;
3961 #endif
3962 #if defined(S_IFBLK)
3963                 case UNIX_TYPE_BLKDEV:
3964                         if (get_current_uid(conn) != sec_initial_uid()) {
3965                                 return NT_STATUS_ACCESS_DENIED;
3966                         }
3967                         unixmode |= S_IFBLK;
3968                         break;
3969 #endif
3970                 default:
3971                         return NT_STATUS_INVALID_PARAMETER;
3972         }
3973
3974         DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
3975                   "%.0f mode 0%o for file %s\n", (double)dev,
3976                   (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
3977
3978         status = parent_pathref(talloc_tos(),
3979                                 conn->cwd_fsp,
3980                                 smb_fname,
3981                                 &parent_fname,
3982                                 &base_name);
3983         if (!NT_STATUS_IS_OK(status)) {
3984                 return status;
3985         }
3986
3987         /* Ok - do the mknod. */
3988         ret = SMB_VFS_MKNODAT(conn,
3989                         parent_fname->fsp,
3990                         base_name,
3991                         unixmode,
3992                         dev);
3993
3994         if (ret != 0) {
3995                 TALLOC_FREE(parent_fname);
3996                 return map_nt_error_from_unix(errno);
3997         }
3998
3999         /* If any of the other "set" calls fail we
4000          * don't want to end up with a half-constructed mknod.
4001          */
4002
4003         if (lp_inherit_permissions(SNUM(conn))) {
4004                 inherit_access_posix_acl(conn,
4005                                          parent_fname->fsp,
4006                                          smb_fname,
4007                                          unixmode);
4008         }
4009         TALLOC_FREE(parent_fname);
4010
4011         return NT_STATUS_OK;
4012 }
4013
4014 /****************************************************************************
4015  Deal with SMB_SET_FILE_UNIX_BASIC.
4016 ****************************************************************************/
4017
4018 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
4019                                         struct smb_request *req,
4020                                         const char *pdata,
4021                                         int total_data,
4022                                         files_struct *fsp,
4023                                         struct smb_filename *smb_fname)
4024 {
4025         struct smb_file_time ft;
4026         uint32_t raw_unixmode;
4027         mode_t unixmode;
4028         off_t size = 0;
4029         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
4030         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
4031         NTSTATUS status = NT_STATUS_OK;
4032         enum perm_type ptype;
4033         files_struct *all_fsps = NULL;
4034         bool modify_mtime = true;
4035         struct file_id id;
4036         SMB_STRUCT_STAT sbuf;
4037
4038         if (!CAN_WRITE(conn)) {
4039                 return NT_STATUS_DOS(ERRSRV, ERRaccess);
4040         }
4041
4042         init_smb_file_time(&ft);
4043
4044         if (total_data < 100) {
4045                 return NT_STATUS_INVALID_PARAMETER;
4046         }
4047
4048         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
4049            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
4050                 size=IVAL(pdata,0); /* first 8 Bytes are size */
4051                 size |= (((off_t)IVAL(pdata,4)) << 32);
4052         }
4053
4054         ft.atime = pull_long_date_full_timespec(pdata+24); /* access_time */
4055         ft.mtime = pull_long_date_full_timespec(pdata+32); /* modification_time */
4056         set_owner = (uid_t)IVAL(pdata,40);
4057         set_grp = (gid_t)IVAL(pdata,48);
4058         raw_unixmode = IVAL(pdata,84);
4059
4060         if (VALID_STAT(smb_fname->st)) {
4061                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
4062                         ptype = PERM_EXISTING_DIR;
4063                 } else {
4064                         ptype = PERM_EXISTING_FILE;
4065                 }
4066         } else {
4067                 ptype = PERM_NEW_FILE;
4068         }
4069
4070         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
4071                                       ptype, &unixmode);
4072         if (!NT_STATUS_IS_OK(status)) {
4073                 return status;
4074         }
4075
4076         DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
4077                   "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
4078                   smb_fname_str_dbg(smb_fname), (double)size,
4079                   (unsigned int)set_owner, (unsigned int)set_grp,
4080                   (int)raw_unixmode));
4081
4082         sbuf = smb_fname->st;
4083
4084         if (!VALID_STAT(sbuf)) {
4085                 /*
4086                  * The only valid use of this is to create character and block
4087                  * devices, and named pipes. This is deprecated (IMHO) and
4088                  * a new info level should be used for mknod. JRA.
4089                  */
4090
4091                 return smb_unix_mknod(conn,
4092                                         pdata,
4093                                         total_data,
4094                                         smb_fname);
4095         }
4096
4097 #if 1
4098         /* Horrible backwards compatibility hack as an old server bug
4099          * allowed a CIFS client bug to remain unnoticed :-(. JRA.
4100          * */
4101
4102         if (!size) {
4103                 size = get_file_size_stat(&sbuf);
4104         }
4105 #endif
4106
4107         /*
4108          * Deal with the UNIX specific mode set.
4109          */
4110
4111         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
4112                 int ret;
4113
4114                 if (fsp == NULL || S_ISLNK(smb_fname->st.st_ex_mode)) {
4115                         DBG_WARNING("Can't set mode on symlink %s\n",
4116                                 smb_fname_str_dbg(smb_fname));
4117                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4118                 }
4119
4120                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
4121                           "setting mode 0%o for file %s\n",
4122                           (unsigned int)unixmode,
4123                           smb_fname_str_dbg(smb_fname)));
4124                 ret = SMB_VFS_FCHMOD(fsp, unixmode);
4125                 if (ret != 0) {
4126                         return map_nt_error_from_unix(errno);
4127                 }
4128         }
4129
4130         /*
4131          * Deal with the UNIX specific uid set.
4132          */
4133
4134         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
4135             (sbuf.st_ex_uid != set_owner)) {
4136                 int ret;
4137
4138                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
4139                           "changing owner %u for path %s\n",
4140                           (unsigned int)set_owner,
4141                           smb_fname_str_dbg(smb_fname)));
4142
4143                 if (fsp &&
4144                     !fsp->fsp_flags.is_pathref &&
4145                     fsp_get_io_fd(fsp) != -1)
4146                 {
4147                         ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
4148                 } else {
4149                         /*
4150                          * UNIX extensions calls must always operate
4151                          * on symlinks.
4152                          */
4153                         ret = SMB_VFS_LCHOWN(conn, smb_fname,
4154                                              set_owner, (gid_t)-1);
4155                 }
4156
4157                 if (ret != 0) {
4158                         status = map_nt_error_from_unix(errno);
4159                         return status;
4160                 }
4161         }
4162
4163         /*
4164          * Deal with the UNIX specific gid set.
4165          */
4166
4167         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
4168             (sbuf.st_ex_gid != set_grp)) {
4169                 int ret;
4170
4171                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
4172                           "changing group %u for file %s\n",
4173                           (unsigned int)set_grp,
4174                           smb_fname_str_dbg(smb_fname)));
4175                 if (fsp &&
4176                     !fsp->fsp_flags.is_pathref &&
4177                     fsp_get_io_fd(fsp) != -1)
4178                 {
4179                         ret = SMB_VFS_FCHOWN(fsp, (uid_t)-1, set_grp);
4180                 } else {
4181                         /*
4182                          * UNIX extensions calls must always operate
4183                          * on symlinks.
4184                          */
4185                         ret = SMB_VFS_LCHOWN(conn, smb_fname, (uid_t)-1,
4186                                   set_grp);
4187                 }
4188                 if (ret != 0) {
4189                         status = map_nt_error_from_unix(errno);
4190                         return status;
4191                 }
4192         }
4193
4194         /* Deal with any size changes. */
4195
4196         if (S_ISREG(sbuf.st_ex_mode)) {
4197                 status = smb_set_file_size(conn, req,
4198                                            fsp,
4199                                            smb_fname,
4200                                            &sbuf,
4201                                            size,
4202                                            false);
4203                 if (!NT_STATUS_IS_OK(status)) {
4204                         return status;
4205                 }
4206         }
4207
4208         /* Deal with any time changes. */
4209         if (is_omit_timespec(&ft.mtime) && is_omit_timespec(&ft.atime)) {
4210                 /* No change, don't cancel anything. */
4211                 return status;
4212         }
4213
4214         id = vfs_file_id_from_sbuf(conn, &sbuf);
4215         for(all_fsps = file_find_di_first(conn->sconn, id, true); all_fsps;
4216                         all_fsps = file_find_di_next(all_fsps, true)) {
4217                 /*
4218                  * We're setting the time explicitly for UNIX.
4219                  * Cancel any pending changes over all handles.
4220                  */
4221                 all_fsps->fsp_flags.update_write_time_on_close = false;
4222                 TALLOC_FREE(all_fsps->update_write_time_event);
4223         }
4224
4225         /*
4226          * Override the "setting_write_time"
4227          * parameter here as it almost does what
4228          * we need. Just remember if we modified
4229          * mtime and send the notify ourselves.
4230          */
4231         if (is_omit_timespec(&ft.mtime)) {
4232                 modify_mtime = false;
4233         }
4234
4235         status = smb_set_file_time(conn,
4236                                 fsp,
4237                                 smb_fname,
4238                                 &ft,
4239                                 false);
4240         if (modify_mtime) {
4241                 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
4242                         FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
4243         }
4244         return status;
4245 }
4246
4247 /****************************************************************************
4248  Deal with SMB_SET_FILE_UNIX_INFO2.
4249 ****************************************************************************/
4250
4251 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
4252                                         struct smb_request *req,
4253                                         const char *pdata,
4254                                         int total_data,
4255                                         files_struct *fsp,
4256                                         struct smb_filename *smb_fname)
4257 {
4258         NTSTATUS status;
4259         uint32_t smb_fflags;
4260         uint32_t smb_fmask;
4261
4262         if (!CAN_WRITE(conn)) {
4263                 return NT_STATUS_DOS(ERRSRV, ERRaccess);
4264         }
4265
4266         if (total_data < 116) {
4267                 return NT_STATUS_INVALID_PARAMETER;
4268         }
4269
4270         /* Start by setting all the fields that are common between UNIX_BASIC
4271          * and UNIX_INFO2.
4272          */
4273         status = smb_set_file_unix_basic(conn, req, pdata, total_data,
4274                                          fsp, smb_fname);
4275         if (!NT_STATUS_IS_OK(status)) {
4276                 return status;
4277         }
4278
4279         smb_fflags = IVAL(pdata, 108);
4280         smb_fmask = IVAL(pdata, 112);
4281
4282         /* NB: We should only attempt to alter the file flags if the client
4283          * sends a non-zero mask.
4284          */
4285         if (smb_fmask != 0) {
4286                 int stat_fflags = 0;
4287
4288                 if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
4289                                              smb_fmask, &stat_fflags)) {
4290                         /* Client asked to alter a flag we don't understand. */
4291                         return NT_STATUS_INVALID_PARAMETER;
4292                 }
4293
4294                 if (fsp == NULL || S_ISLNK(smb_fname->st.st_ex_mode)) {
4295                         DBG_WARNING("Can't change flags on symlink %s\n",
4296                                 smb_fname_str_dbg(smb_fname));
4297                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4298                 }
4299                 if (SMB_VFS_FCHFLAGS(fsp, stat_fflags) != 0) {
4300                         return map_nt_error_from_unix(errno);
4301                 }
4302         }
4303
4304         /* XXX: need to add support for changing the create_time here. You
4305          * can do this for paths on Darwin with setattrlist(2). The right way
4306          * to hook this up is probably by extending the VFS utimes interface.
4307          */
4308
4309         return NT_STATUS_OK;
4310 }
4311
4312 /****************************************************************************
4313  Deal with SMB_SET_POSIX_ACL.
4314 ****************************************************************************/
4315
4316 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
4317                                 struct smb_request *req,
4318                                 const char *pdata,
4319                                 int total_data_in,
4320                                 files_struct *fsp,
4321                                 struct smb_filename *smb_fname)
4322 {
4323 #if !defined(HAVE_POSIX_ACLS)
4324         return NT_STATUS_INVALID_LEVEL;
4325 #else
4326         uint16_t posix_acl_version;
4327         uint16_t num_file_acls;
4328         uint16_t num_def_acls;
4329         bool valid_file_acls = true;
4330         bool valid_def_acls = true;
4331         NTSTATUS status;
4332         unsigned int size_needed;
4333         unsigned int total_data;
4334         bool close_fsp = false;
4335
4336         if (total_data_in < 0) {
4337                 status = NT_STATUS_INVALID_PARAMETER;
4338                 goto out;
4339         }
4340
4341         total_data = total_data_in;
4342
4343         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
4344                 status = NT_STATUS_INVALID_PARAMETER;
4345                 goto out;
4346         }
4347         posix_acl_version = SVAL(pdata,0);
4348         num_file_acls = SVAL(pdata,2);
4349         num_def_acls = SVAL(pdata,4);
4350
4351         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4352                 valid_file_acls = false;
4353                 num_file_acls = 0;
4354         }
4355
4356         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4357                 valid_def_acls = false;
4358                 num_def_acls = 0;
4359         }
4360
4361         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
4362                 status = NT_STATUS_INVALID_PARAMETER;
4363                 goto out;
4364         }
4365
4366         /* Wrap checks. */
4367         if (num_file_acls + num_def_acls < num_file_acls) {
4368                 status = NT_STATUS_INVALID_PARAMETER;
4369                 goto out;
4370         }
4371
4372         size_needed = num_file_acls + num_def_acls;
4373
4374         /*
4375          * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
4376          * than UINT_MAX, so check by division.
4377          */
4378         if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
4379                 status = NT_STATUS_INVALID_PARAMETER;
4380                 goto out;
4381         }
4382
4383         size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
4384         if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
4385                 status = NT_STATUS_INVALID_PARAMETER;
4386                 goto out;
4387         }
4388         size_needed += SMB_POSIX_ACL_HEADER_SIZE;
4389
4390         if (total_data < size_needed) {
4391                 status = NT_STATUS_INVALID_PARAMETER;
4392                 goto out;
4393         }
4394
4395         /*
4396          * Ensure we always operate on a file descriptor, not just
4397          * the filename.
4398          */
4399         if (fsp == NULL || !fsp->fsp_flags.is_fsa) {
4400                 uint32_t access_mask = SEC_STD_WRITE_OWNER|
4401                                         SEC_STD_WRITE_DAC|
4402                                         SEC_STD_READ_CONTROL|
4403                                         FILE_READ_ATTRIBUTES|
4404                                         FILE_WRITE_ATTRIBUTES;
4405
4406                 status = get_posix_fsp(conn,
4407                                         req,
4408                                         smb_fname,
4409                                         access_mask,
4410                                         &fsp);
4411
4412                 if (!NT_STATUS_IS_OK(status)) {
4413                         goto out;
4414                 }
4415                 close_fsp = true;
4416         }
4417
4418         /* Here we know fsp != NULL */
4419         SMB_ASSERT(fsp != NULL);
4420
4421         status = refuse_symlink_fsp(fsp);
4422         if (!NT_STATUS_IS_OK(status)) {
4423                 goto out;
4424         }
4425
4426         /* If we have a default acl, this *must* be a directory. */
4427         if (valid_def_acls && !fsp->fsp_flags.is_directory) {
4428                 DBG_INFO("Can't set default acls on "
4429                          "non-directory %s\n",
4430                          fsp_str_dbg(fsp));
4431                 return NT_STATUS_INVALID_HANDLE;
4432         }
4433
4434         DBG_DEBUG("file %s num_file_acls = %"PRIu16", "
4435                   "num_def_acls = %"PRIu16"\n",
4436                   fsp_str_dbg(fsp),
4437                   num_file_acls,
4438                   num_def_acls);
4439
4440         /* Move pdata to the start of the file ACL entries. */
4441         pdata += SMB_POSIX_ACL_HEADER_SIZE;
4442
4443         if (valid_file_acls) {
4444                 status = set_unix_posix_acl(conn,
4445                                         fsp,
4446                                         num_file_acls,
4447                                         pdata);
4448                 if (!NT_STATUS_IS_OK(status)) {
4449                         goto out;
4450                 }
4451         }
4452
4453         /* Move pdata to the start of the default ACL entries. */
4454         pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
4455
4456         if (valid_def_acls) {
4457                 status = set_unix_posix_default_acl(conn,
4458                                         fsp,
4459                                         num_def_acls,
4460                                         pdata);
4461                 if (!NT_STATUS_IS_OK(status)) {
4462                         goto out;
4463                 }
4464         }
4465
4466         status = NT_STATUS_OK;
4467
4468   out:
4469
4470         if (close_fsp) {
4471                 (void)close_file_free(req, &fsp, NORMAL_CLOSE);
4472         }
4473         return status;
4474 #endif
4475 }
4476
4477 static void call_trans2setpathinfo(
4478         connection_struct *conn,
4479         struct smb_request *req,
4480         char **pparams,
4481         int total_params,
4482         char **ppdata,
4483         int total_data,
4484         unsigned int max_data_bytes)
4485 {
4486         uint16_t info_level;
4487         struct smb_filename *smb_fname = NULL;
4488         struct files_struct *dirfsp = NULL;
4489         struct files_struct *fsp = NULL;
4490         char *params = *pparams;
4491         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
4492         NTTIME twrp = 0;
4493         char *fname = NULL;
4494         bool info_level_handled;
4495         int data_return_size = 0;
4496         NTSTATUS status;
4497
4498         if (params == NULL) {
4499                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4500                 return;
4501         }
4502
4503         /* set path info */
4504         if (total_params < 7) {
4505                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4506                 return;
4507         }
4508
4509         info_level = SVAL(params,0);
4510
4511         if (INFO_LEVEL_IS_UNIX(info_level)) {
4512                 if (!lp_smb1_unix_extensions()) {
4513                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4514                         return;
4515                 }
4516                 if (!req->posix_pathnames) {
4517                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4518                         return;
4519                 }
4520         }
4521
4522         if (req->posix_pathnames) {
4523                 srvstr_get_path_posix(req,
4524                                       params,
4525                                       req->flags2,
4526                                       &fname,
4527                                       &params[6],
4528                                       total_params - 6,
4529                                       STR_TERMINATE,
4530                                       &status);
4531         } else {
4532                 srvstr_get_path(req,
4533                                 params,
4534                                 req->flags2,
4535                                 &fname,
4536                                 &params[6],
4537                                 total_params - 6,
4538                                 STR_TERMINATE,
4539                                 &status);
4540         }
4541         if (!NT_STATUS_IS_OK(status)) {
4542                 reply_nterror(req, status);
4543                 return;
4544         }
4545
4546         DBG_NOTICE("fname=%s info_level=%d totdata=%d\n",
4547                    fname,
4548                    info_level,
4549                    total_data);
4550
4551         if (ucf_flags & UCF_GMT_PATHNAME) {
4552                 extract_snapshot_token(fname, &twrp);
4553         }
4554         status = smb1_strip_dfs_path(req, &ucf_flags, &fname);
4555         if (!NT_STATUS_IS_OK(status)) {
4556                 reply_nterror(req, status);
4557                 return;
4558         }
4559         status = filename_convert_dirfsp(req,
4560                                          conn,
4561                                          fname,
4562                                          ucf_flags,
4563                                          twrp,
4564                                          &dirfsp,
4565                                          &smb_fname);
4566         if (!NT_STATUS_IS_OK(status)) {
4567                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4568                         reply_botherror(req,
4569                                         NT_STATUS_PATH_NOT_COVERED,
4570                                         ERRSRV, ERRbadpath);
4571                         return;
4572                 }
4573                 reply_nterror(req, status);
4574                 return;
4575         }
4576
4577         info_level_handled = true; /* Untouched in switch cases below */
4578
4579         switch (info_level) {
4580
4581         default:
4582                 info_level_handled = false;
4583                 break;
4584
4585         case SMB_POSIX_PATH_OPEN:
4586                 status = smb_posix_open(
4587                         conn,
4588                         req,
4589                         ppdata,
4590                         total_data,
4591                         smb_fname,
4592                         &data_return_size);
4593                 break;
4594
4595         case SMB_POSIX_PATH_UNLINK:
4596                 status = smb_posix_unlink(
4597                         conn, req, *ppdata, total_data, smb_fname);
4598                 break;
4599
4600         case SMB_SET_FILE_UNIX_LINK:
4601                 status = smb_set_file_unix_link(
4602                         conn, req, *ppdata, total_data, smb_fname);
4603                 break;
4604
4605         case SMB_SET_FILE_UNIX_HLINK:
4606                 status = smb_set_file_unix_hlink(
4607                         conn, req, *ppdata, total_data, smb_fname);
4608                 break;
4609
4610         case SMB_SET_FILE_UNIX_BASIC:
4611                 status = smb_set_file_unix_basic(
4612                         conn,
4613                         req,
4614                         *ppdata,
4615                         total_data,
4616                         smb_fname->fsp,
4617                         smb_fname);
4618                 break;
4619
4620         case SMB_SET_FILE_UNIX_INFO2:
4621                 status = smb_set_file_unix_info2(
4622                         conn,
4623                         req,
4624                         *ppdata,
4625                         total_data,
4626                         smb_fname->fsp,
4627                         smb_fname);
4628                 break;
4629         case SMB_SET_POSIX_ACL:
4630                 status = smb_set_posix_acl(
4631                         conn, req, *ppdata, total_data, NULL, smb_fname);
4632                 break;
4633         }
4634
4635         if (info_level_handled) {
4636                 handle_trans2setfilepathinfo_result(
4637                         conn,
4638                         req,
4639                         info_level,
4640                         status,
4641                         *ppdata,
4642                         data_return_size,
4643                         max_data_bytes);
4644                 return;
4645         }
4646
4647         /*
4648          * smb_fname->fsp may be NULL if smb_fname points at a symlink
4649          * and we're in POSIX context, so be careful when using fsp
4650          * below, it can still be NULL.
4651          */
4652         fsp = smb_fname->fsp;
4653
4654         status = smbd_do_setfilepathinfo(
4655                 conn,
4656                 req,
4657                 req,
4658                 info_level,
4659                 fsp,
4660                 smb_fname,
4661                 ppdata,
4662                 total_data,
4663                 &data_return_size);
4664
4665         handle_trans2setfilepathinfo_result(
4666                 conn,
4667                 req,
4668                 info_level,
4669                 status,
4670                 *ppdata,
4671                 data_return_size,
4672                 max_data_bytes);
4673 }
4674
4675 static void call_trans2setfileinfo(
4676         connection_struct *conn,
4677         struct smb_request *req,
4678         char **pparams,
4679         int total_params,
4680         char **ppdata,
4681         int total_data,
4682         unsigned int max_data_bytes)
4683 {
4684         char *pdata = *ppdata;
4685         uint16_t info_level;
4686         struct smb_filename *smb_fname = NULL;
4687         struct files_struct *fsp = NULL;
4688         char *params = *pparams;
4689         int data_return_size = 0;
4690         bool info_level_handled;
4691         NTSTATUS status;
4692         int ret;
4693
4694         if (params == NULL) {
4695                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4696                 return;
4697         }
4698         if (total_params < 4) {
4699                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4700                 return;
4701         }
4702
4703         fsp = file_fsp(req, SVAL(params,0));
4704         /* Basic check for non-null fsp. */
4705         if (!check_fsp_open(conn, req, fsp)) {
4706                 return;
4707         }
4708         info_level = SVAL(params,2);
4709
4710         if (INFO_LEVEL_IS_UNIX(info_level)) {
4711                 if (!lp_smb1_unix_extensions()) {
4712                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4713                         return;
4714                 }
4715                 if (!req->posix_pathnames) {
4716                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4717                         return;
4718                 }
4719         }
4720
4721         smb_fname = fsp->fsp_name;
4722
4723         DBG_NOTICE("fnum=%s fname=%s info_level=%d totdata=%d\n",
4724                    fsp_fnum_dbg(fsp),
4725                    fsp_str_dbg(fsp),
4726                    info_level,
4727                    total_data);
4728
4729         if (fsp_get_pathref_fd(fsp) == -1) {
4730                 /*
4731                  * This is actually a SETFILEINFO on a directory
4732                  * handle (returned from an NT SMB). NT5.0 seems
4733                  * to do this call. JRA.
4734                  */
4735                 ret = vfs_stat(conn, smb_fname);
4736                 if (ret != 0) {
4737                         DBG_NOTICE("vfs_stat of %s failed (%s)\n",
4738                                    smb_fname_str_dbg(smb_fname),
4739                                    strerror(errno));
4740                         reply_nterror(req, map_nt_error_from_unix(errno));
4741                         return;
4742                 }
4743         } else if (fsp->print_file) {
4744                 /*
4745                  * Doing a DELETE_ON_CLOSE should cancel a print job.
4746                  */
4747                 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) &&
4748                     CVAL(pdata,0)) {
4749
4750                         fsp->fsp_flags.delete_on_close = true;
4751
4752                         DBG_NOTICE("Cancelling print job (%s)\n",
4753                                    fsp_str_dbg(fsp));
4754
4755                         SSVAL(params,0,0);
4756                         send_trans2_replies(
4757                                 conn,
4758                                 req,
4759                                 NT_STATUS_OK,
4760                                 params,
4761                                 2,
4762                                 *ppdata, 0,
4763                                 max_data_bytes);
4764                         return;
4765                 } else {
4766                         reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
4767                         return;
4768                 }
4769         } else {
4770                 /*
4771                  * Original code - this is an open file.
4772                  */
4773                 status = vfs_stat_fsp(fsp);
4774                 if (!NT_STATUS_IS_OK(status)) {
4775                         DBG_NOTICE("fstat of %s failed (%s)\n",
4776                                    fsp_fnum_dbg(fsp),
4777                                    nt_errstr(status));
4778                         reply_nterror(req, status);
4779                         return;
4780                 }
4781         }
4782
4783         info_level_handled = true; /* Untouched in switch cases below */
4784
4785         switch (info_level) {
4786
4787         default:
4788                 info_level_handled = false;
4789                 break;
4790
4791         case SMB_SET_FILE_UNIX_BASIC:
4792                 status = smb_set_file_unix_basic(
4793                         conn, req, pdata, total_data, fsp, smb_fname);
4794                 break;
4795
4796         case SMB_SET_FILE_UNIX_INFO2:
4797                 status = smb_set_file_unix_info2(
4798                         conn, req, pdata, total_data, fsp, smb_fname);
4799                 break;
4800
4801         case SMB_SET_POSIX_LOCK:
4802                 status = smb_set_posix_lock(
4803                         conn, req, *ppdata, total_data, fsp);
4804                 break;
4805         }
4806
4807         if (info_level_handled) {
4808                 handle_trans2setfilepathinfo_result(
4809                         conn,
4810                         req,
4811                         info_level,
4812                         status,
4813                         *ppdata,
4814                         data_return_size,
4815                         max_data_bytes);
4816                 return;
4817         }
4818
4819         status = smbd_do_setfilepathinfo(
4820                 conn,
4821                 req,
4822                 req,
4823                 info_level,
4824                 fsp,
4825                 smb_fname,
4826                 ppdata,
4827                 total_data,
4828                 &data_return_size);
4829
4830         handle_trans2setfilepathinfo_result(
4831                 conn,
4832                 req,
4833                 info_level,
4834                 status,
4835                 *ppdata,
4836                 data_return_size,
4837                 max_data_bytes);
4838 }
4839
4840 /****************************************************************************
4841  Reply to a TRANS2_MKDIR (make directory with extended attributes).
4842 ****************************************************************************/
4843
4844 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
4845                              char **pparams, int total_params,
4846                              char **ppdata, int total_data,
4847                              unsigned int max_data_bytes)
4848 {
4849         struct files_struct *dirfsp = NULL;
4850         struct files_struct *fsp = NULL;
4851         struct smb_filename *smb_dname = NULL;
4852         char *params = *pparams;
4853         char *pdata = *ppdata;
4854         char *directory = NULL;
4855         NTSTATUS status = NT_STATUS_OK;
4856         struct ea_list *ea_list = NULL;
4857         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
4858         NTTIME twrp = 0;
4859         TALLOC_CTX *ctx = talloc_tos();
4860
4861         if (!CAN_WRITE(conn)) {
4862                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4863                 return;
4864         }
4865
4866         if (total_params < 5) {
4867                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4868                 return;
4869         }
4870
4871         if (req->posix_pathnames) {
4872                 srvstr_get_path_posix(ctx,
4873                         params,
4874                         req->flags2,
4875                         &directory,
4876                         &params[4],
4877                         total_params - 4,
4878                         STR_TERMINATE,
4879                         &status);
4880         } else {
4881                 srvstr_get_path(ctx,
4882                         params,
4883                         req->flags2,
4884                         &directory,
4885                         &params[4],
4886                         total_params - 4,
4887                         STR_TERMINATE,
4888                         &status);
4889         }
4890         if (!NT_STATUS_IS_OK(status)) {
4891                 reply_nterror(req, status);
4892                 return;
4893         }
4894
4895         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
4896
4897         if (ucf_flags & UCF_GMT_PATHNAME) {
4898                 extract_snapshot_token(directory, &twrp);
4899         }
4900         status = smb1_strip_dfs_path(ctx, &ucf_flags, &directory);
4901         if (!NT_STATUS_IS_OK(status)) {
4902                 reply_nterror(req, status);
4903                 goto out;
4904         }
4905         status = filename_convert_dirfsp(ctx,
4906                                          conn,
4907                                          directory,
4908                                          ucf_flags,
4909                                          twrp,
4910                                          &dirfsp,
4911                                          &smb_dname);
4912         if (!NT_STATUS_IS_OK(status)) {
4913                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4914                         reply_botherror(req,
4915                                 NT_STATUS_PATH_NOT_COVERED,
4916                                 ERRSRV, ERRbadpath);
4917                         return;
4918                 }
4919                 reply_nterror(req, status);
4920                 return;
4921         }
4922
4923         /*
4924          * OS/2 workplace shell seems to send SET_EA requests of "null"
4925          * length (4 bytes containing IVAL 4).
4926          * They seem to have no effect. Bug #3212. JRA.
4927          */
4928
4929         if (total_data && (total_data != 4)) {
4930                 /* Any data in this call is an EA list. */
4931                 if (total_data < 10) {
4932                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4933                         goto out;
4934                 }
4935
4936                 if (IVAL(pdata,0) > total_data) {
4937                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
4938                                 IVAL(pdata,0), (unsigned int)total_data));
4939                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4940                         goto out;
4941                 }
4942
4943                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
4944                                        total_data - 4);
4945                 if (!ea_list) {
4946                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4947                         goto out;
4948                 }
4949
4950                 if (!lp_ea_support(SNUM(conn))) {
4951                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
4952                         goto out;
4953                 }
4954         }
4955         /* If total_data == 4 Windows doesn't care what values
4956          * are placed in that field, it just ignores them.
4957          * The System i QNTC IBM SMB client puts bad values here,
4958          * so ignore them. */
4959
4960         status = SMB_VFS_CREATE_FILE(
4961                 conn,                                   /* conn */
4962                 req,                                    /* req */
4963                 dirfsp,                                 /* dirfsp */
4964                 smb_dname,                              /* fname */
4965                 MAXIMUM_ALLOWED_ACCESS,                 /* access_mask */
4966                 FILE_SHARE_NONE,                        /* share_access */
4967                 FILE_CREATE,                            /* create_disposition*/
4968                 FILE_DIRECTORY_FILE,                    /* create_options */
4969                 FILE_ATTRIBUTE_DIRECTORY,               /* file_attributes */
4970                 0,                                      /* oplock_request */
4971                 NULL,                                   /* lease */
4972                 0,                                      /* allocation_size */
4973                 0,                                      /* private_flags */
4974                 NULL,                                   /* sd */
4975                 NULL,                                   /* ea_list */
4976                 &fsp,                                   /* result */
4977                 NULL,                                   /* pinfo */
4978                 NULL, NULL);                            /* create context */
4979         if (!NT_STATUS_IS_OK(status)) {
4980                 reply_nterror(req, status);
4981                 goto out;
4982         }
4983
4984         /* Try and set any given EA. */
4985         if (ea_list) {
4986                 status = set_ea(conn, fsp, ea_list);
4987                 if (!NT_STATUS_IS_OK(status)) {
4988                         reply_nterror(req, status);
4989                         goto out;
4990                 }
4991         }
4992
4993         /* Realloc the parameter and data sizes */
4994         *pparams = (char *)SMB_REALLOC(*pparams,2);
4995         if(*pparams == NULL) {
4996                 reply_nterror(req, NT_STATUS_NO_MEMORY);
4997                 goto out;
4998         }
4999         params = *pparams;
5000
5001         SSVAL(params,0,0);
5002
5003         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, 0, max_data_bytes);
5004
5005  out:
5006         if (fsp != NULL) {
5007                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
5008         }
5009         TALLOC_FREE(smb_dname);
5010         return;
5011 }
5012
5013 /****************************************************************************
5014  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
5015  We don't actually do this - we just send a null response.
5016 ****************************************************************************/
5017
5018 static void call_trans2findnotifyfirst(connection_struct *conn,
5019                                        struct smb_request *req,
5020                                        char **pparams, int total_params,
5021                                        char **ppdata, int total_data,
5022                                        unsigned int max_data_bytes)
5023 {
5024         char *params = *pparams;
5025         uint16_t info_level;
5026
5027         if (total_params < 6) {
5028                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5029                 return;
5030         }
5031
5032         info_level = SVAL(params,4);
5033         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
5034
5035         switch (info_level) {
5036                 case 1:
5037                 case 2:
5038                         break;
5039                 default:
5040                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5041                         return;
5042         }
5043
5044         /* Realloc the parameter and data sizes */
5045         *pparams = (char *)SMB_REALLOC(*pparams,6);
5046         if (*pparams == NULL) {
5047                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5048                 return;
5049         }
5050         params = *pparams;
5051
5052         SSVAL(params,0,fnf_handle);
5053         SSVAL(params,2,0); /* No changes */
5054         SSVAL(params,4,0); /* No EA errors */
5055
5056         fnf_handle++;
5057
5058         if(fnf_handle == 0)
5059                 fnf_handle = 257;
5060
5061         send_trans2_replies(conn, req, NT_STATUS_OK, params, 6, *ppdata, 0, max_data_bytes);
5062
5063         return;
5064 }
5065
5066 /****************************************************************************
5067  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
5068  changes). Currently this does nothing.
5069 ****************************************************************************/
5070
5071 static void call_trans2findnotifynext(connection_struct *conn,
5072                                       struct smb_request *req,
5073                                       char **pparams, int total_params,
5074                                       char **ppdata, int total_data,
5075                                       unsigned int max_data_bytes)
5076 {
5077         char *params = *pparams;
5078
5079         DEBUG(3,("call_trans2findnotifynext\n"));
5080
5081         /* Realloc the parameter and data sizes */
5082         *pparams = (char *)SMB_REALLOC(*pparams,4);
5083         if (*pparams == NULL) {
5084                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5085                 return;
5086         }
5087         params = *pparams;
5088
5089         SSVAL(params,0,0); /* No changes */
5090         SSVAL(params,2,0); /* No EA errors */
5091
5092         send_trans2_replies(conn, req, NT_STATUS_OK, params, 4, *ppdata, 0, max_data_bytes);
5093
5094         return;
5095 }
5096
5097 /****************************************************************************
5098  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
5099 ****************************************************************************/
5100
5101 static void call_trans2getdfsreferral(connection_struct *conn,
5102                                       struct smb_request *req,
5103                                       char **pparams, int total_params,
5104                                       char **ppdata, int total_data,
5105                                       unsigned int max_data_bytes)
5106 {
5107         char *params = *pparams;
5108         char *pathname = NULL;
5109         int reply_size = 0;
5110         int max_referral_level;
5111         NTSTATUS status = NT_STATUS_OK;
5112         TALLOC_CTX *ctx = talloc_tos();
5113
5114         DEBUG(10,("call_trans2getdfsreferral\n"));
5115
5116         if (!IS_IPC(conn)) {
5117                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
5118                 return;
5119         }
5120
5121         if (total_params < 3) {
5122                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5123                 return;
5124         }
5125
5126         max_referral_level = SVAL(params,0);
5127
5128         if(!lp_host_msdfs()) {
5129                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
5130                 return;
5131         }
5132
5133         srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
5134                     total_params - 2, STR_TERMINATE);
5135         if (!pathname) {
5136                 reply_nterror(req, NT_STATUS_NOT_FOUND);
5137                 return;
5138         }
5139         reply_size = setup_dfs_referral(
5140                 conn, pathname, max_referral_level, ppdata, &status);
5141         if (reply_size < 0) {
5142                 reply_nterror(req, status);
5143                 return;
5144         }
5145
5146         SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
5147               SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
5148         send_trans2_replies(conn, req, NT_STATUS_OK, 0,0,*ppdata,reply_size, max_data_bytes);
5149
5150         return;
5151 }
5152
5153 #define LMCAT_SPL       0x53
5154 #define LMFUNC_GETJOBID 0x60
5155
5156 /****************************************************************************
5157  Reply to a TRANS2_IOCTL - used for OS/2 printing.
5158 ****************************************************************************/
5159
5160 static void call_trans2ioctl(connection_struct *conn,
5161                              struct smb_request *req,
5162                              char **pparams, int total_params,
5163                              char **ppdata, int total_data,
5164                              unsigned int max_data_bytes)
5165 {
5166         const struct loadparm_substitution *lp_sub =
5167                 loadparm_s3_global_substitution();
5168         char *pdata = *ppdata;
5169         files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
5170         NTSTATUS status;
5171         size_t len = 0;
5172
5173         /* check for an invalid fid before proceeding */
5174
5175         if (!fsp) {
5176                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
5177                 return;
5178         }
5179
5180         if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
5181             && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
5182                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
5183                 if (*ppdata == NULL) {
5184                         reply_nterror(req, NT_STATUS_NO_MEMORY);
5185                         return;
5186                 }
5187                 pdata = *ppdata;
5188
5189                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
5190                         CAN ACCEPT THIS IN UNICODE. JRA. */
5191
5192                 /* Job number */
5193                 SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
5194
5195                 status = srvstr_push(pdata, req->flags2, pdata + 2,
5196                             lp_netbios_name(), 15,
5197                             STR_ASCII|STR_TERMINATE, &len); /* Our NetBIOS name */
5198                 if (!NT_STATUS_IS_OK(status)) {
5199                         reply_nterror(req, status);
5200                         return;
5201                 }
5202                 status = srvstr_push(pdata, req->flags2, pdata+18,
5203                             lp_servicename(talloc_tos(), lp_sub, SNUM(conn)), 13,
5204                             STR_ASCII|STR_TERMINATE, &len); /* Service name */
5205                 if (!NT_STATUS_IS_OK(status)) {
5206                         reply_nterror(req, status);
5207                         return;
5208                 }
5209                 send_trans2_replies(conn, req, NT_STATUS_OK, *pparams, 0, *ppdata, 32,
5210                                     max_data_bytes);
5211                 return;
5212         }
5213
5214         DEBUG(2,("Unknown TRANS2_IOCTL\n"));
5215         reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
5216 }
5217
5218 static void handle_trans2(connection_struct *conn, struct smb_request *req,
5219                           struct trans_state *state)
5220 {
5221         if (get_Protocol() >= PROTOCOL_NT1) {
5222                 req->flags2 |= 0x40; /* IS_LONG_NAME */
5223                 SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
5224         }
5225
5226         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
5227                 if (state->call != TRANSACT2_QFSINFO &&
5228                     state->call != TRANSACT2_SETFSINFO) {
5229                         DEBUG(0,("handle_trans2: encryption required "
5230                                 "with call 0x%x\n",
5231                                 (unsigned int)state->call));
5232                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
5233                         return;
5234                 }
5235         }
5236
5237         /* Now we must call the relevant TRANS2 function */
5238         switch(state->call)  {
5239         case TRANSACT2_OPEN:
5240         {
5241                 START_PROFILE(Trans2_open);
5242                 call_trans2open(conn, req,
5243                                 &state->param, state->total_param,
5244                                 &state->data, state->total_data,
5245                                 state->max_data_return);
5246                 END_PROFILE(Trans2_open);
5247                 break;
5248         }
5249
5250         case TRANSACT2_FINDFIRST:
5251         {
5252                 START_PROFILE(Trans2_findfirst);
5253                 call_trans2findfirst(conn, req,
5254                                      &state->param, state->total_param,
5255                                      &state->data, state->total_data,
5256                                      state->max_data_return);
5257                 END_PROFILE(Trans2_findfirst);
5258                 break;
5259         }
5260
5261         case TRANSACT2_FINDNEXT:
5262         {
5263                 START_PROFILE(Trans2_findnext);
5264                 call_trans2findnext(conn, req,
5265                                     &state->param, state->total_param,
5266                                     &state->data, state->total_data,
5267                                     state->max_data_return);
5268                 END_PROFILE(Trans2_findnext);
5269                 break;
5270         }
5271
5272         case TRANSACT2_QFSINFO:
5273         {
5274                 START_PROFILE(Trans2_qfsinfo);
5275                 call_trans2qfsinfo(conn, req,
5276                                    &state->param, state->total_param,
5277                                    &state->data, state->total_data,
5278                                    state->max_data_return);
5279                 END_PROFILE(Trans2_qfsinfo);
5280             break;
5281         }
5282
5283         case TRANSACT2_SETFSINFO:
5284         {
5285                 START_PROFILE(Trans2_setfsinfo);
5286                 call_trans2setfsinfo(conn, req,
5287                                      &state->param, state->total_param,
5288                                      &state->data, state->total_data,
5289                                      state->max_data_return);
5290                 END_PROFILE(Trans2_setfsinfo);
5291                 break;
5292         }
5293
5294         case TRANSACT2_QPATHINFO:
5295         {
5296                 START_PROFILE(Trans2_qpathinfo);
5297                 call_trans2qpathinfo(
5298                         conn,
5299                         req,
5300                         &state->param,
5301                         state->total_param,
5302                         &state->data,
5303                         state->total_data,
5304                         state->max_data_return);
5305                 END_PROFILE(Trans2_qpathinfo);
5306                 break;
5307         }
5308
5309         case TRANSACT2_QFILEINFO:
5310         {
5311                 START_PROFILE(Trans2_qfileinfo);
5312                 call_trans2qfileinfo(
5313                         conn,
5314                         req,
5315                         &state->param,
5316                         state->total_param,
5317                         &state->data,
5318                         state->total_data,
5319                         state->max_data_return);
5320                 END_PROFILE(Trans2_qfileinfo);
5321                 break;
5322         }
5323
5324         case TRANSACT2_SETPATHINFO:
5325         {
5326                 START_PROFILE(Trans2_setpathinfo);
5327                 call_trans2setpathinfo(
5328                         conn,
5329                         req,
5330                         &state->param,
5331                         state->total_param,
5332                         &state->data,
5333                         state->total_data,
5334                         state->max_data_return);
5335                 END_PROFILE(Trans2_setpathinfo);
5336                 break;
5337         }
5338
5339         case TRANSACT2_SETFILEINFO:
5340         {
5341                 START_PROFILE(Trans2_setfileinfo);
5342                 call_trans2setfileinfo(
5343                         conn,
5344                         req,
5345                         &state->param,
5346                         state->total_param,
5347                         &state->data,
5348                         state->total_data,
5349                         state->max_data_return);
5350                 END_PROFILE(Trans2_setfileinfo);
5351                 break;
5352         }
5353
5354         case TRANSACT2_FINDNOTIFYFIRST:
5355         {
5356                 START_PROFILE(Trans2_findnotifyfirst);
5357                 call_trans2findnotifyfirst(conn, req,
5358                                            &state->param, state->total_param,
5359                                            &state->data, state->total_data,
5360                                            state->max_data_return);
5361                 END_PROFILE(Trans2_findnotifyfirst);
5362                 break;
5363         }
5364
5365         case TRANSACT2_FINDNOTIFYNEXT:
5366         {
5367                 START_PROFILE(Trans2_findnotifynext);
5368                 call_trans2findnotifynext(conn, req,
5369                                           &state->param, state->total_param,
5370                                           &state->data, state->total_data,
5371                                           state->max_data_return);
5372                 END_PROFILE(Trans2_findnotifynext);
5373                 break;
5374         }
5375
5376         case TRANSACT2_MKDIR:
5377         {
5378                 START_PROFILE(Trans2_mkdir);
5379                 call_trans2mkdir(conn, req,
5380                                  &state->param, state->total_param,
5381                                  &state->data, state->total_data,
5382                                  state->max_data_return);
5383                 END_PROFILE(Trans2_mkdir);
5384                 break;
5385         }
5386
5387         case TRANSACT2_GET_DFS_REFERRAL:
5388         {
5389                 START_PROFILE(Trans2_get_dfs_referral);
5390                 call_trans2getdfsreferral(conn, req,
5391                                           &state->param, state->total_param,
5392                                           &state->data, state->total_data,
5393                                           state->max_data_return);
5394                 END_PROFILE(Trans2_get_dfs_referral);
5395                 break;
5396         }
5397
5398         case TRANSACT2_IOCTL:
5399         {
5400                 START_PROFILE(Trans2_ioctl);
5401                 call_trans2ioctl(conn, req,
5402                                  &state->param, state->total_param,
5403                                  &state->data, state->total_data,
5404                                  state->max_data_return);
5405                 END_PROFILE(Trans2_ioctl);
5406                 break;
5407         }
5408
5409         default:
5410                 /* Error in request */
5411                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
5412                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
5413         }
5414 }
5415
5416 /****************************************************************************
5417  Reply to a SMBtrans2.
5418  ****************************************************************************/
5419
5420 void reply_trans2(struct smb_request *req)
5421 {
5422         connection_struct *conn = req->conn;
5423         unsigned int dsoff;
5424         unsigned int dscnt;
5425         unsigned int psoff;
5426         unsigned int pscnt;
5427         unsigned int tran_call;
5428         struct trans_state *state;
5429         NTSTATUS result;
5430
5431         START_PROFILE(SMBtrans2);
5432
5433         if (req->wct < 14) {
5434                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5435                 END_PROFILE(SMBtrans2);
5436                 return;
5437         }
5438
5439         dsoff = SVAL(req->vwv+12, 0);
5440         dscnt = SVAL(req->vwv+11, 0);
5441         psoff = SVAL(req->vwv+10, 0);
5442         pscnt = SVAL(req->vwv+9, 0);
5443         tran_call = SVAL(req->vwv+14, 0);
5444
5445         result = allow_new_trans(conn->pending_trans, req->mid);
5446         if (!NT_STATUS_IS_OK(result)) {
5447                 DEBUG(2, ("Got invalid trans2 request: %s\n",
5448                           nt_errstr(result)));
5449                 reply_nterror(req, result);
5450                 END_PROFILE(SMBtrans2);
5451                 return;
5452         }
5453
5454         if (IS_IPC(conn)) {
5455                 switch (tran_call) {
5456                 /* List the allowed trans2 calls on IPC$ */
5457                 case TRANSACT2_OPEN:
5458                 case TRANSACT2_GET_DFS_REFERRAL:
5459                 case TRANSACT2_QFILEINFO:
5460                 case TRANSACT2_QFSINFO:
5461                 case TRANSACT2_SETFSINFO:
5462                         break;
5463                 default:
5464                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
5465                         END_PROFILE(SMBtrans2);
5466                         return;
5467                 }
5468         }
5469
5470         if ((state = talloc(conn, struct trans_state)) == NULL) {
5471                 DEBUG(0, ("talloc failed\n"));
5472                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5473                 END_PROFILE(SMBtrans2);
5474                 return;
5475         }
5476
5477         state->cmd = SMBtrans2;
5478
5479         state->mid = req->mid;
5480         state->vuid = req->vuid;
5481         state->setup_count = SVAL(req->vwv+13, 0);
5482         state->setup = NULL;
5483         state->total_param = SVAL(req->vwv+0, 0);
5484         state->param = NULL;
5485         state->total_data =  SVAL(req->vwv+1, 0);
5486         state->data = NULL;
5487         state->max_param_return = SVAL(req->vwv+2, 0);
5488         state->max_data_return  = SVAL(req->vwv+3, 0);
5489         state->max_setup_return = SVAL(req->vwv+4, 0);
5490         state->close_on_completion = BITSETW(req->vwv+5, 0);
5491         state->one_way = BITSETW(req->vwv+5, 1);
5492
5493         state->call = tran_call;
5494
5495         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
5496            is so as a sanity check */
5497         if (state->setup_count != 1) {
5498                 /*
5499                  * Need to have rc=0 for ioctl to get job id for OS/2.
5500                  *  Network printing will fail if function is not successful.
5501                  *  Similar function in reply.c will be used if protocol
5502                  *  is LANMAN1.0 instead of LM1.2X002.
5503                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
5504                  *  outbuf doesn't have to be set(only job id is used).
5505                  */
5506                 if ( (state->setup_count == 4)
5507                      && (tran_call == TRANSACT2_IOCTL)
5508                      && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
5509                      && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
5510                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
5511                 } else {
5512                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
5513                         DEBUG(2,("Transaction is %d\n",tran_call));
5514                         TALLOC_FREE(state);
5515                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5516                         END_PROFILE(SMBtrans2);
5517                         return;
5518                 }
5519         }
5520
5521         if ((dscnt > state->total_data) || (pscnt > state->total_param))
5522                 goto bad_param;
5523
5524         if (state->total_data) {
5525
5526                 if (smb_buffer_oob(state->total_data, 0, dscnt)
5527                     || smb_buffer_oob(smb_len(req->inbuf), dsoff, dscnt)) {
5528                         goto bad_param;
5529                 }
5530
5531                 /* Can't use talloc here, the core routines do realloc on the
5532                  * params and data. */
5533                 state->data = (char *)SMB_MALLOC(state->total_data);
5534                 if (state->data == NULL) {
5535                         DEBUG(0,("reply_trans2: data malloc fail for %u "
5536                                  "bytes !\n", (unsigned int)state->total_data));
5537                         TALLOC_FREE(state);
5538                         reply_nterror(req, NT_STATUS_NO_MEMORY);
5539                         END_PROFILE(SMBtrans2);
5540                         return;
5541                 }
5542
5543                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
5544         }
5545
5546         if (state->total_param) {
5547
5548                 if (smb_buffer_oob(state->total_param, 0, pscnt)
5549                     || smb_buffer_oob(smb_len(req->inbuf), psoff, pscnt)) {
5550                         goto bad_param;
5551                 }
5552
5553                 /* Can't use talloc here, the core routines do realloc on the
5554                  * params and data. */
5555                 state->param = (char *)SMB_MALLOC(state->total_param);
5556                 if (state->param == NULL) {
5557                         DEBUG(0,("reply_trans: param malloc fail for %u "
5558                                  "bytes !\n", (unsigned int)state->total_param));
5559                         SAFE_FREE(state->data);
5560                         TALLOC_FREE(state);
5561                         reply_nterror(req, NT_STATUS_NO_MEMORY);
5562                         END_PROFILE(SMBtrans2);
5563                         return;
5564                 }
5565
5566                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
5567         }
5568
5569         state->received_data  = dscnt;
5570         state->received_param = pscnt;
5571
5572         if ((state->received_param == state->total_param) &&
5573             (state->received_data == state->total_data)) {
5574
5575                 handle_trans2(conn, req, state);
5576
5577                 SAFE_FREE(state->data);
5578                 SAFE_FREE(state->param);
5579                 TALLOC_FREE(state);
5580                 END_PROFILE(SMBtrans2);
5581                 return;
5582         }
5583
5584         DLIST_ADD(conn->pending_trans, state);
5585
5586         /* We need to send an interim response then receive the rest
5587            of the parameter/data bytes */
5588         reply_smb1_outbuf(req, 0, 0);
5589         show_msg((char *)req->outbuf);
5590         END_PROFILE(SMBtrans2);
5591         return;
5592
5593   bad_param:
5594
5595         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
5596         SAFE_FREE(state->data);
5597         SAFE_FREE(state->param);
5598         TALLOC_FREE(state);
5599         END_PROFILE(SMBtrans2);
5600         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5601 }
5602
5603 /****************************************************************************
5604  Reply to a SMBtranss2
5605  ****************************************************************************/
5606
5607 void reply_transs2(struct smb_request *req)
5608 {
5609         connection_struct *conn = req->conn;
5610         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
5611         struct trans_state *state;
5612
5613         START_PROFILE(SMBtranss2);
5614
5615         show_msg((const char *)req->inbuf);
5616
5617         /* Windows clients expect all replies to
5618            a transact secondary (SMBtranss2 0x33)
5619            to have a command code of transact
5620            (SMBtrans2 0x32). See bug #8989
5621            and also [MS-CIFS] section 2.2.4.47.2
5622            for details.
5623         */
5624         req->cmd = SMBtrans2;
5625
5626         if (req->wct < 8) {
5627                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5628                 END_PROFILE(SMBtranss2);
5629                 return;
5630         }
5631
5632         for (state = conn->pending_trans; state != NULL;
5633              state = state->next) {
5634                 if (state->mid == req->mid) {
5635                         break;
5636                 }
5637         }
5638
5639         if ((state == NULL) || (state->cmd != SMBtrans2)) {
5640                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5641                 END_PROFILE(SMBtranss2);
5642                 return;
5643         }
5644
5645         /* Revise state->total_param and state->total_data in case they have
5646            changed downwards */
5647
5648         if (SVAL(req->vwv+0, 0) < state->total_param)
5649                 state->total_param = SVAL(req->vwv+0, 0);
5650         if (SVAL(req->vwv+1, 0) < state->total_data)
5651                 state->total_data = SVAL(req->vwv+1, 0);
5652
5653         pcnt = SVAL(req->vwv+2, 0);
5654         poff = SVAL(req->vwv+3, 0);
5655         pdisp = SVAL(req->vwv+4, 0);
5656
5657         dcnt = SVAL(req->vwv+5, 0);
5658         doff = SVAL(req->vwv+6, 0);
5659         ddisp = SVAL(req->vwv+7, 0);
5660
5661         state->received_param += pcnt;
5662         state->received_data += dcnt;
5663
5664         if ((state->received_data > state->total_data) ||
5665             (state->received_param > state->total_param))
5666                 goto bad_param;
5667
5668         if (pcnt) {
5669                 if (smb_buffer_oob(state->total_param, pdisp, pcnt)
5670                     || smb_buffer_oob(smb_len(req->inbuf), poff, pcnt)) {
5671                         goto bad_param;
5672                 }
5673                 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
5674         }
5675
5676         if (dcnt) {
5677                 if (smb_buffer_oob(state->total_data, ddisp, dcnt)
5678                     || smb_buffer_oob(smb_len(req->inbuf), doff, dcnt)) {
5679                         goto bad_param;
5680                 }
5681                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
5682         }
5683
5684         if ((state->received_param < state->total_param) ||
5685             (state->received_data < state->total_data)) {
5686                 END_PROFILE(SMBtranss2);
5687                 return;
5688         }
5689
5690         handle_trans2(conn, req, state);
5691
5692         DLIST_REMOVE(conn->pending_trans, state);
5693         SAFE_FREE(state->data);
5694         SAFE_FREE(state->param);
5695         TALLOC_FREE(state);
5696
5697         END_PROFILE(SMBtranss2);
5698         return;
5699
5700   bad_param:
5701
5702         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
5703         DLIST_REMOVE(conn->pending_trans, state);
5704         SAFE_FREE(state->data);
5705         SAFE_FREE(state->param);
5706         TALLOC_FREE(state);
5707         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5708         END_PROFILE(SMBtranss2);
5709         return;
5710 }