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