LCOV - code coverage report
Current view: top level - source3/smbd - smb1_trans2.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 134 1573 8.5 %
Date: 2024-06-13 04:01:37 Functions: 4 21 19.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB transaction2 handling
       4             :    Copyright (C) Jeremy Allison                 1994-2007
       5             :    Copyright (C) Stefan (metze) Metzmacher      2003
       6             :    Copyright (C) Volker Lendecke                2005-2007
       7             :    Copyright (C) Steve French                   2005
       8             :    Copyright (C) James Peach                    2006-2007
       9             : 
      10             :    Extensively modified by Andrew Tridgell, 1995
      11             : 
      12             :    This program is free software; you can redistribute it and/or modify
      13             :    it under the terms of the GNU General Public License as published by
      14             :    the Free Software Foundation; either version 3 of the License, or
      15             :    (at your option) any later version.
      16             : 
      17             :    This program is distributed in the hope that it will be useful,
      18             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             :    GNU General Public License for more details.
      21             : 
      22             :    You should have received a copy of the GNU General Public License
      23             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24             : */
      25             : 
      26             : #include "includes.h"
      27             : #include "ntioctl.h"
      28             : #include "system/filesys.h"
      29             : #include "lib/util/time_basic.h"
      30             : #include "version.h"
      31             : #include "smbd/smbd.h"
      32             : #include "smbd/globals.h"
      33             : #include "../libcli/auth/libcli_auth.h"
      34             : #include "../librpc/gen_ndr/xattr.h"
      35             : #include "../librpc/gen_ndr/ndr_security.h"
      36             : #include "libcli/security/security.h"
      37             : #include "trans2.h"
      38             : #include "auth.h"
      39             : #include "smbprofile.h"
      40             : #include "rpc_server/srv_pipe_hnd.h"
      41             : #include "printing.h"
      42             : #include "lib/util_ea.h"
      43             : #include "lib/readdir_attr.h"
      44             : #include "messages.h"
      45             : #include "libcli/smb/smb2_posix.h"
      46             : #include "lib/util/string_wrappers.h"
      47             : #include "source3/lib/substitute.h"
      48             : #include "source3/lib/adouble.h"
      49             : 
      50             : #define DIR_ENTRY_SAFETY_MARGIN 4096
      51             : 
      52             : /****************************************************************************
      53             :   Send the required number of replies back.
      54             :   We assume all fields other than the data fields are
      55             :   set correctly for the type of call.
      56             :   HACK ! Always assumes smb_setup field is zero.
      57             : ****************************************************************************/
      58             : 
      59           8 : void send_trans2_replies(connection_struct *conn,
      60             :                         struct smb_request *req,
      61             :                         NTSTATUS status,
      62             :                          const char *params,
      63             :                          int paramsize,
      64             :                          const char *pdata,
      65             :                          int datasize,
      66             :                          int max_data_bytes)
      67             : {
      68             :         /* As we are using a protocol > LANMAN1 then the max_send
      69             :          variable must have been set in the sessetupX call.
      70             :          This takes precedence over the max_xmit field in the
      71             :          global struct. These different max_xmit variables should
      72             :          be merged as this is now too confusing */
      73             : 
      74           8 :         int data_to_send = datasize;
      75           8 :         int params_to_send = paramsize;
      76             :         int useable_space;
      77           8 :         const char *pp = params;
      78           8 :         const char *pd = pdata;
      79             :         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
      80           8 :         int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
      81           8 :         int data_alignment_offset = 0;
      82           8 :         bool overflow = False;
      83           8 :         struct smbXsrv_connection *xconn = req->xconn;
      84           8 :         int max_send = xconn->smb1.sessions.max_send;
      85             : 
      86             :         /* Modify the data_to_send and datasize and set the error if
      87             :            we're trying to send more than max_data_bytes. We still send
      88             :            the part of the packet(s) that fit. Strange, but needed
      89             :            for OS/2. */
      90             : 
      91           8 :         if (max_data_bytes > 0 && datasize > max_data_bytes) {
      92           0 :                 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
      93             :                         max_data_bytes, datasize ));
      94           0 :                 datasize = data_to_send = max_data_bytes;
      95           0 :                 overflow = True;
      96             :         }
      97             : 
      98             :         /* If there genuinely are no parameters or data to send just send the empty packet */
      99             : 
     100           8 :         if(params_to_send == 0 && data_to_send == 0) {
     101           0 :                 reply_smb1_outbuf(req, 10, 0);
     102           0 :                 if (NT_STATUS_V(status)) {
     103             :                         uint8_t eclass;
     104             :                         uint32_t ecode;
     105           0 :                         ntstatus_to_dos(status, &eclass, &ecode);
     106           0 :                         error_packet_set((char *)req->outbuf,
     107             :                                         eclass, ecode, status,
     108             :                                         __LINE__,__FILE__);
     109             :                 }
     110           0 :                 show_msg((char *)req->outbuf);
     111           0 :                 if (!smb1_srv_send(xconn,
     112           0 :                                 (char *)req->outbuf,
     113           0 :                                 true, req->seqnum+1,
     114           0 :                                 IS_CONN_ENCRYPTED(conn),
     115             :                                 &req->pcd)) {
     116           0 :                         exit_server_cleanly("send_trans2_replies: smb1_srv_send failed.");
     117             :                 }
     118           0 :                 TALLOC_FREE(req->outbuf);
     119           0 :                 return;
     120             :         }
     121             : 
     122             :         /* When sending params and data ensure that both are nicely aligned */
     123             :         /* Only do this alignment when there is also data to send - else
     124             :                 can cause NT redirector problems. */
     125             : 
     126           8 :         if (((params_to_send % 4) != 0) && (data_to_send != 0))
     127           0 :                 data_alignment_offset = 4 - (params_to_send % 4);
     128             : 
     129             :         /* Space is bufsize minus Netbios over TCP header minus SMB header */
     130             :         /* The alignment_offset is to align the param bytes on an even byte
     131             :                 boundary. NT 4.0 Beta needs this to work correctly. */
     132             : 
     133           8 :         useable_space = max_send - (smb_size
     134             :                                     + 2 * 10 /* wct */
     135           8 :                                     + alignment_offset
     136           8 :                                     + data_alignment_offset);
     137             : 
     138           8 :         if (useable_space < 0) {
     139           0 :                 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
     140             :                           "= %d!!!", useable_space));
     141           0 :                 exit_server_cleanly("send_trans2_replies: Not enough space");
     142             :         }
     143             : 
     144          20 :         while (params_to_send || data_to_send) {
     145             :                 /* Calculate whether we will totally or partially fill this packet */
     146             : 
     147           8 :                 total_sent_thistime = params_to_send + data_to_send;
     148             : 
     149             :                 /* We can never send more than useable_space */
     150             :                 /*
     151             :                  * Note that 'useable_space' does not include the alignment offsets,
     152             :                  * but we must include the alignment offsets in the calculation of
     153             :                  * the length of the data we send over the wire, as the alignment offsets
     154             :                  * are sent here. Fix from Marc_Jacobsen@hp.com.
     155             :                  */
     156             : 
     157           8 :                 total_sent_thistime = MIN(total_sent_thistime, useable_space);
     158             : 
     159          12 :                 reply_smb1_outbuf(req, 10, total_sent_thistime + alignment_offset
     160           8 :                              + data_alignment_offset);
     161             : 
     162             :                 /* Set total params and data to be sent */
     163           8 :                 SSVAL(req->outbuf,smb_tprcnt,paramsize);
     164           8 :                 SSVAL(req->outbuf,smb_tdrcnt,datasize);
     165             : 
     166             :                 /* Calculate how many parameters and data we can fit into
     167             :                  * this packet. Parameters get precedence
     168             :                  */
     169             : 
     170           8 :                 params_sent_thistime = MIN(params_to_send,useable_space);
     171           8 :                 data_sent_thistime = useable_space - params_sent_thistime;
     172           8 :                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
     173             : 
     174           8 :                 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
     175             : 
     176             :                 /* smb_proff is the offset from the start of the SMB header to the
     177             :                         parameter bytes, however the first 4 bytes of outbuf are
     178             :                         the Netbios over TCP header. Thus use smb_base() to subtract
     179             :                         them from the calculation */
     180             : 
     181           8 :                 SSVAL(req->outbuf,smb_proff,
     182             :                       ((smb_buf(req->outbuf)+alignment_offset)
     183             :                        - smb_base(req->outbuf)));
     184             : 
     185           8 :                 if(params_sent_thistime == 0)
     186           8 :                         SSVAL(req->outbuf,smb_prdisp,0);
     187             :                 else
     188             :                         /* Absolute displacement of param bytes sent in this packet */
     189           0 :                         SSVAL(req->outbuf,smb_prdisp,pp - params);
     190             : 
     191           8 :                 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
     192           8 :                 if(data_sent_thistime == 0) {
     193           0 :                         SSVAL(req->outbuf,smb_droff,0);
     194           0 :                         SSVAL(req->outbuf,smb_drdisp, 0);
     195             :                 } else {
     196             :                         /* The offset of the data bytes is the offset of the
     197             :                                 parameter bytes plus the number of parameters being sent this time */
     198           8 :                         SSVAL(req->outbuf, smb_droff,
     199             :                               ((smb_buf(req->outbuf)+alignment_offset)
     200             :                                - smb_base(req->outbuf))
     201             :                               + params_sent_thistime + data_alignment_offset);
     202           8 :                         SSVAL(req->outbuf,smb_drdisp, pd - pdata);
     203             :                 }
     204             : 
     205             :                 /* Initialize the padding for alignment */
     206             : 
     207           8 :                 if (alignment_offset != 0) {
     208           8 :                         memset(smb_buf(req->outbuf), 0, alignment_offset);
     209             :                 }
     210             : 
     211             :                 /* Copy the param bytes into the packet */
     212             : 
     213           8 :                 if(params_sent_thistime) {
     214           0 :                         memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
     215             :                                params_sent_thistime);
     216             :                 }
     217             : 
     218             :                 /* Copy in the data bytes */
     219           8 :                 if(data_sent_thistime) {
     220           8 :                         if (data_alignment_offset != 0) {
     221           0 :                                 memset((smb_buf(req->outbuf)+alignment_offset+
     222             :                                         params_sent_thistime), 0,
     223             :                                        data_alignment_offset);
     224             :                         }
     225          12 :                         memcpy(smb_buf(req->outbuf)+alignment_offset
     226           8 :                                +params_sent_thistime+data_alignment_offset,
     227             :                                pd,data_sent_thistime);
     228             :                 }
     229             : 
     230           8 :                 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
     231             :                         params_sent_thistime, data_sent_thistime, useable_space));
     232           8 :                 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
     233             :                         params_to_send, data_to_send, paramsize, datasize));
     234             : 
     235           8 :                 if (overflow) {
     236           0 :                         error_packet_set((char *)req->outbuf,
     237             :                                          ERRDOS,ERRbufferoverflow,
     238           0 :                                          STATUS_BUFFER_OVERFLOW,
     239             :                                          __LINE__,__FILE__);
     240           8 :                 } else if (NT_STATUS_V(status)) {
     241             :                         uint8_t eclass;
     242             :                         uint32_t ecode;
     243           0 :                         ntstatus_to_dos(status, &eclass, &ecode);
     244           0 :                         error_packet_set((char *)req->outbuf,
     245             :                                         eclass, ecode, status,
     246             :                                         __LINE__,__FILE__);
     247             :                 }
     248             : 
     249             :                 /* Send the packet */
     250           8 :                 show_msg((char *)req->outbuf);
     251          20 :                 if (!smb1_srv_send(xconn,
     252           8 :                                 (char *)req->outbuf,
     253           8 :                                 true, req->seqnum+1,
     254           8 :                                 IS_CONN_ENCRYPTED(conn),
     255             :                                 &req->pcd))
     256           0 :                         exit_server_cleanly("send_trans2_replies: smb1_srv_send failed.");
     257             : 
     258           8 :                 TALLOC_FREE(req->outbuf);
     259             : 
     260           8 :                 pp += params_sent_thistime;
     261           8 :                 pd += data_sent_thistime;
     262             : 
     263           8 :                 params_to_send -= params_sent_thistime;
     264           8 :                 data_to_send -= data_sent_thistime;
     265             : 
     266             :                 /* Sanity check */
     267           8 :                 if(params_to_send < 0 || data_to_send < 0) {
     268           0 :                         DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
     269             :                                 params_to_send, data_to_send));
     270           0 :                         return;
     271             :                 }
     272             :         }
     273             : 
     274           8 :         return;
     275             : }
     276             : 
     277             : /****************************************************************************
     278             :  Deal with SMB_SET_POSIX_LOCK.
     279             : ****************************************************************************/
     280             : 
     281             : static void smb_set_posix_lock_done(struct tevent_req *subreq);
     282             : 
     283           0 : NTSTATUS smb_set_posix_lock(connection_struct *conn,
     284             :                             struct smb_request *req,
     285             :                             const char *pdata,
     286             :                             int total_data,
     287             :                             files_struct *fsp)
     288             : {
     289           0 :         struct tevent_req *subreq = NULL;
     290           0 :         struct smbd_lock_element *lck = NULL;
     291             :         uint64_t count;
     292             :         uint64_t offset;
     293             :         uint64_t smblctx;
     294           0 :         bool blocking_lock = False;
     295             :         enum brl_type lock_type;
     296             : 
     297           0 :         NTSTATUS status = NT_STATUS_OK;
     298             : 
     299           0 :         if (fsp == NULL ||
     300           0 :             fsp->fsp_flags.is_pathref ||
     301           0 :             fsp_get_io_fd(fsp) == -1)
     302             :         {
     303           0 :                 return NT_STATUS_INVALID_HANDLE;
     304             :         }
     305             : 
     306           0 :         if (total_data != POSIX_LOCK_DATA_SIZE) {
     307           0 :                 return NT_STATUS_INVALID_PARAMETER;
     308             :         }
     309             : 
     310           0 :         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
     311           0 :                 case POSIX_LOCK_TYPE_READ:
     312           0 :                         lock_type = READ_LOCK;
     313           0 :                         break;
     314           0 :                 case POSIX_LOCK_TYPE_WRITE:
     315             :                         /* Return the right POSIX-mappable error code for files opened read-only. */
     316           0 :                         if (!fsp->fsp_flags.can_write) {
     317           0 :                                 return NT_STATUS_INVALID_HANDLE;
     318             :                         }
     319           0 :                         lock_type = WRITE_LOCK;
     320           0 :                         break;
     321           0 :                 case POSIX_LOCK_TYPE_UNLOCK:
     322           0 :                         lock_type = UNLOCK_LOCK;
     323           0 :                         break;
     324           0 :                 default:
     325           0 :                         return NT_STATUS_INVALID_PARAMETER;
     326             :         }
     327             : 
     328           0 :         switch (SVAL(pdata, POSIX_LOCK_FLAGS_OFFSET)) {
     329           0 :         case POSIX_LOCK_FLAG_NOWAIT:
     330           0 :                 blocking_lock = false;
     331           0 :                 break;
     332           0 :         case POSIX_LOCK_FLAG_WAIT:
     333           0 :                 blocking_lock = true;
     334           0 :                 break;
     335           0 :         default:
     336           0 :                 return NT_STATUS_INVALID_PARAMETER;
     337             :         }
     338             : 
     339           0 :         if (!lp_blocking_locks(SNUM(conn))) {
     340           0 :                 blocking_lock = False;
     341             :         }
     342             : 
     343           0 :         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
     344           0 :         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
     345           0 :                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
     346           0 :         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
     347           0 :                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
     348             : 
     349           0 :         DBG_DEBUG("file %s, lock_type = %u, smblctx = %"PRIu64", "
     350             :                   "count = %"PRIu64", offset = %"PRIu64"\n",
     351             :                   fsp_str_dbg(fsp),
     352             :                   (unsigned int)lock_type,
     353             :                   smblctx,
     354             :                   count,
     355             :                   offset);
     356             : 
     357           0 :         if (lock_type == UNLOCK_LOCK) {
     358           0 :                 struct smbd_lock_element l = {
     359           0 :                         .req_guid = smbd_request_guid(req, 0),
     360             :                         .smblctx = smblctx,
     361             :                         .brltype = UNLOCK_LOCK,
     362             :                         .lock_flav = POSIX_LOCK,
     363             :                         .offset = offset,
     364             :                         .count = count,
     365             :                 };
     366           0 :                 status = smbd_do_unlocking(req, fsp, 1, &l);
     367           0 :                 return status;
     368             :         }
     369             : 
     370           0 :         lck = talloc(req, struct smbd_lock_element);
     371           0 :         if (lck == NULL) {
     372           0 :                 return NT_STATUS_NO_MEMORY;
     373             :         }
     374             : 
     375           0 :         *lck = (struct smbd_lock_element) {
     376           0 :                 .req_guid = smbd_request_guid(req, 0),
     377             :                 .smblctx = smblctx,
     378             :                 .brltype = lock_type,
     379             :                 .lock_flav = POSIX_LOCK,
     380             :                 .count = count,
     381             :                 .offset = offset,
     382             :         };
     383             : 
     384           0 :         subreq = smbd_smb1_do_locks_send(
     385             :                 fsp,
     386           0 :                 req->sconn->ev_ctx,
     387             :                 &req,
     388             :                 fsp,
     389             :                 blocking_lock ? UINT32_MAX : 0,
     390             :                 true,           /* large_offset */
     391             :                 1,
     392             :                 lck);
     393           0 :         if (subreq == NULL) {
     394           0 :                 TALLOC_FREE(lck);
     395           0 :                 return NT_STATUS_NO_MEMORY;
     396             :         }
     397           0 :         tevent_req_set_callback(subreq, smb_set_posix_lock_done, req);
     398           0 :         return NT_STATUS_EVENT_PENDING;
     399             : }
     400             : 
     401           0 : static void smb_set_posix_lock_done(struct tevent_req *subreq)
     402             : {
     403           0 :         struct smb_request *req = NULL;
     404             :         NTSTATUS status;
     405             :         bool ok;
     406             : 
     407           0 :         ok = smbd_smb1_do_locks_extract_smbreq(subreq, talloc_tos(), &req);
     408           0 :         SMB_ASSERT(ok);
     409             : 
     410           0 :         status = smbd_smb1_do_locks_recv(subreq);
     411           0 :         TALLOC_FREE(subreq);
     412             : 
     413           0 :         if (NT_STATUS_IS_OK(status)) {
     414           0 :                 char params[2] = {0};
     415             :                 /* Fake up max_data_bytes here - we know it fits. */
     416           0 :                 send_trans2_replies(
     417           0 :                         req->conn,
     418             :                         req,
     419           0 :                         NT_STATUS_OK,
     420             :                         params,
     421             :                         2,
     422             :                         NULL,
     423             :                         0,
     424             :                         0xffff);
     425             :         } else {
     426           0 :                 reply_nterror(req, status);
     427           0 :                 ok = smb1_srv_send(
     428           0 :                         req->xconn,
     429           0 :                         (char *)req->outbuf,
     430             :                         true,
     431           0 :                         req->seqnum+1,
     432           0 :                         IS_CONN_ENCRYPTED(req->conn),
     433             :                         NULL);
     434           0 :                 if (!ok) {
     435           0 :                         exit_server_cleanly("smb_set_posix_lock_done: "
     436             :                                             "smb1_srv_send failed.");
     437             :                 }
     438             :         }
     439             : 
     440           0 :         TALLOC_FREE(req);
     441           0 :         return;
     442             : }
     443             : 
     444             : /****************************************************************************
     445             :  Read a list of EA names from an incoming data buffer. Create an ea_list with them.
     446             : ****************************************************************************/
     447             : 
     448           0 : static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
     449             : {
     450           0 :         struct ea_list *ea_list_head = NULL;
     451           0 :         size_t converted_size, offset = 0;
     452             : 
     453           0 :         while (offset + 2 < data_size) {
     454           0 :                 struct ea_list *eal = talloc_zero(ctx, struct ea_list);
     455           0 :                 unsigned int namelen = CVAL(pdata,offset);
     456             : 
     457           0 :                 offset++; /* Go past the namelen byte. */
     458             : 
     459             :                 /* integer wrap paranioa. */
     460           0 :                 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
     461           0 :                                 (offset > data_size) || (namelen > data_size) ||
     462           0 :                                 (offset + namelen >= data_size)) {
     463             :                         break;
     464             :                 }
     465             :                 /* Ensure the name is null terminated. */
     466           0 :                 if (pdata[offset + namelen] != '\0') {
     467           0 :                         return NULL;
     468             :                 }
     469           0 :                 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
     470             :                                        &converted_size)) {
     471           0 :                         DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
     472             :                                  "failed: %s", strerror(errno)));
     473             :                 }
     474           0 :                 if (!eal->ea.name) {
     475           0 :                         return NULL;
     476             :                 }
     477             : 
     478           0 :                 offset += (namelen + 1); /* Go past the name + terminating zero. */
     479           0 :                 DLIST_ADD_END(ea_list_head, eal);
     480           0 :                 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
     481             :         }
     482             : 
     483           0 :         return ea_list_head;
     484             : }
     485             : 
     486             : /****************************************************************************
     487             :  Reply to a TRANSACT2_OPEN.
     488             : ****************************************************************************/
     489             : 
     490           0 : static void call_trans2open(connection_struct *conn,
     491             :                             struct smb_request *req,
     492             :                             char **pparams, int total_params,
     493             :                             char **ppdata, int total_data,
     494             :                             unsigned int max_data_bytes)
     495             : {
     496           0 :         struct smb_filename *smb_fname = NULL;
     497           0 :         char *params = *pparams;
     498           0 :         char *pdata = *ppdata;
     499             :         int deny_mode;
     500             :         int32_t open_attr;
     501             :         bool oplock_request;
     502             : #if 0
     503             :         bool return_additional_info;
     504             :         int16 open_sattr;
     505             :         time_t open_time;
     506             : #endif
     507             :         int open_ofun;
     508             :         uint32_t open_size;
     509             :         char *pname;
     510           0 :         char *fname = NULL;
     511           0 :         off_t size=0;
     512           0 :         int fattr=0,mtime=0;
     513           0 :         SMB_INO_T inode = 0;
     514           0 :         int smb_action = 0;
     515           0 :         struct files_struct *dirfsp = NULL;
     516             :         files_struct *fsp;
     517           0 :         struct ea_list *ea_list = NULL;
     518           0 :         uint16_t flags = 0;
     519             :         NTSTATUS status;
     520             :         uint32_t access_mask;
     521             :         uint32_t share_mode;
     522             :         uint32_t create_disposition;
     523           0 :         uint32_t create_options = 0;
     524           0 :         uint32_t private_flags = 0;
     525           0 :         NTTIME twrp = 0;
     526           0 :         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
     527           0 :         TALLOC_CTX *ctx = talloc_tos();
     528             : 
     529             :         /*
     530             :          * Ensure we have enough parameters to perform the operation.
     531             :          */
     532             : 
     533           0 :         if (total_params < 29) {
     534           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     535           0 :                 goto out;
     536             :         }
     537             : 
     538           0 :         flags = SVAL(params, 0);
     539           0 :         deny_mode = SVAL(params, 2);
     540           0 :         open_attr = SVAL(params,6);
     541           0 :         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
     542           0 :         if (oplock_request) {
     543           0 :                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
     544             :         }
     545             : 
     546             : #if 0
     547             :         return_additional_info = BITSETW(params,0);
     548             :         open_sattr = SVAL(params, 4);
     549             :         open_time = make_unix_date3(params+8);
     550             : #endif
     551           0 :         open_ofun = SVAL(params,12);
     552           0 :         open_size = IVAL(params,14);
     553           0 :         pname = &params[28];
     554             : 
     555           0 :         if (IS_IPC(conn)) {
     556           0 :                 reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
     557           0 :                 goto out;
     558             :         }
     559             : 
     560           0 :         if (req->posix_pathnames) {
     561           0 :                 srvstr_get_path_posix(ctx,
     562             :                         params,
     563           0 :                         req->flags2,
     564             :                         &fname,
     565             :                         pname,
     566           0 :                         total_params - 28,
     567             :                         STR_TERMINATE,
     568             :                         &status);
     569             :         } else {
     570           0 :                 srvstr_get_path(ctx,
     571             :                         params,
     572           0 :                         req->flags2,
     573             :                         &fname,
     574             :                         pname,
     575           0 :                         total_params - 28,
     576             :                         STR_TERMINATE,
     577             :                         &status);
     578             :         }
     579           0 :         if (!NT_STATUS_IS_OK(status)) {
     580           0 :                 reply_nterror(req, status);
     581           0 :                 goto out;
     582             :         }
     583             : 
     584           0 :         DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
     585             :                 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
     586             :                 (unsigned int)open_ofun, open_size));
     587             : 
     588           0 :         if (ucf_flags & UCF_GMT_PATHNAME) {
     589           0 :                 extract_snapshot_token(fname, &twrp);
     590             :         }
     591           0 :         status = filename_convert_dirfsp(ctx,
     592             :                                          conn,
     593             :                                          fname,
     594             :                                          ucf_flags,
     595             :                                          twrp,
     596             :                                          &dirfsp,
     597             :                                          &smb_fname);
     598           0 :         if (!NT_STATUS_IS_OK(status)) {
     599           0 :                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
     600           0 :                         reply_botherror(req,
     601             :                                 NT_STATUS_PATH_NOT_COVERED,
     602             :                                 ERRSRV, ERRbadpath);
     603           0 :                         goto out;
     604             :                 }
     605           0 :                 reply_nterror(req, status);
     606           0 :                 goto out;
     607             :         }
     608             : 
     609           0 :         if (open_ofun == 0) {
     610           0 :                 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
     611           0 :                 goto out;
     612             :         }
     613             : 
     614           0 :         if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
     615             :                                          open_ofun,
     616             :                                          &access_mask, &share_mode,
     617             :                                          &create_disposition,
     618             :                                          &create_options,
     619             :                                          &private_flags)) {
     620           0 :                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
     621           0 :                 goto out;
     622             :         }
     623             : 
     624             :         /* Any data in this call is an EA list. */
     625           0 :         if (total_data && (total_data != 4)) {
     626           0 :                 if (total_data < 10) {
     627           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     628           0 :                         goto out;
     629             :                 }
     630             : 
     631           0 :                 if (IVAL(pdata,0) > total_data) {
     632           0 :                         DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
     633             :                                 IVAL(pdata,0), (unsigned int)total_data));
     634           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     635           0 :                         goto out;
     636             :                 }
     637             : 
     638           0 :                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
     639           0 :                                        total_data - 4);
     640           0 :                 if (!ea_list) {
     641           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     642           0 :                         goto out;
     643             :                 }
     644             : 
     645           0 :                 if (!lp_ea_support(SNUM(conn))) {
     646           0 :                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
     647           0 :                         goto out;
     648             :                 }
     649             : 
     650           0 :                 if (!req->posix_pathnames &&
     651           0 :                                 ea_list_has_invalid_name(ea_list)) {
     652           0 :                         int param_len = 30;
     653           0 :                         *pparams = (char *)SMB_REALLOC(*pparams, param_len);
     654           0 :                         if(*pparams == NULL ) {
     655           0 :                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
     656           0 :                                 goto out;
     657             :                         }
     658           0 :                         params = *pparams;
     659           0 :                         memset(params, '\0', param_len);
     660           0 :                         send_trans2_replies(conn, req, STATUS_INVALID_EA_NAME,
     661             :                                 params, param_len, NULL, 0, max_data_bytes);
     662           0 :                         goto out;
     663             :                 }
     664             :         }
     665             : 
     666           0 :         status = SMB_VFS_CREATE_FILE(
     667             :                 conn,                                   /* conn */
     668             :                 req,                                    /* req */
     669             :                 dirfsp,                                 /* dirfsp */
     670             :                 smb_fname,                              /* fname */
     671             :                 access_mask,                            /* access_mask */
     672             :                 share_mode,                             /* share_access */
     673             :                 create_disposition,                     /* create_disposition*/
     674             :                 create_options,                         /* create_options */
     675             :                 open_attr,                              /* file_attributes */
     676             :                 oplock_request,                         /* oplock_request */
     677             :                 NULL,                                   /* lease */
     678             :                 open_size,                              /* allocation_size */
     679             :                 private_flags,
     680             :                 NULL,                                   /* sd */
     681             :                 ea_list,                                /* ea_list */
     682             :                 &fsp,                                       /* result */
     683             :                 &smb_action,                                /* psbuf */
     684             :                 NULL, NULL);                            /* create context */
     685             : 
     686           0 :         if (!NT_STATUS_IS_OK(status)) {
     687           0 :                 if (open_was_deferred(req->xconn, req->mid)) {
     688             :                         /* We have re-scheduled this call. */
     689           0 :                         goto out;
     690             :                 }
     691             : 
     692           0 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
     693           0 :                         reply_openerror(req, status);
     694           0 :                         goto out;
     695             :                 }
     696             : 
     697           0 :                 fsp = fcb_or_dos_open(
     698             :                         req,
     699             :                         smb_fname,
     700             :                         access_mask,
     701             :                         create_options,
     702             :                         private_flags);
     703           0 :                 if (fsp == NULL) {
     704           0 :                         bool ok = defer_smb1_sharing_violation(req);
     705           0 :                         if (ok) {
     706           0 :                                 goto out;
     707             :                         }
     708           0 :                         reply_openerror(req, status);
     709           0 :                         goto out;
     710             :                 }
     711             : 
     712           0 :                 smb_action = FILE_WAS_OPENED;
     713             :         }
     714             : 
     715           0 :         size = get_file_size_stat(&smb_fname->st);
     716           0 :         fattr = fdos_mode(fsp);
     717           0 :         mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
     718           0 :         inode = smb_fname->st.st_ex_ino;
     719           0 :         if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
     720           0 :                 close_file_free(req, &fsp, ERROR_CLOSE);
     721           0 :                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
     722           0 :                 goto out;
     723             :         }
     724             : 
     725             :         /* Realloc the size of parameters and data we will return */
     726           0 :         *pparams = (char *)SMB_REALLOC(*pparams, 30);
     727           0 :         if(*pparams == NULL ) {
     728           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
     729           0 :                 goto out;
     730             :         }
     731           0 :         params = *pparams;
     732             : 
     733           0 :         SSVAL(params,0,fsp->fnum);
     734           0 :         SSVAL(params,2,fattr);
     735           0 :         srv_put_dos_date2(params,4, mtime);
     736           0 :         SIVAL(params,8, (uint32_t)size);
     737           0 :         SSVAL(params,12,deny_mode);
     738           0 :         SSVAL(params,14,0); /* open_type - file or directory. */
     739           0 :         SSVAL(params,16,0); /* open_state - only valid for IPC device. */
     740             : 
     741           0 :         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
     742           0 :                 smb_action |= EXTENDED_OPLOCK_GRANTED;
     743             :         }
     744             : 
     745           0 :         SSVAL(params,18,smb_action);
     746             : 
     747             :         /*
     748             :          * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
     749             :          */
     750           0 :         SIVAL(params,20,inode);
     751           0 :         SSVAL(params,24,0); /* Padding. */
     752           0 :         if (flags & 8) {
     753           0 :                 uint32_t ea_size = estimate_ea_size(smb_fname->fsp);
     754           0 :                 SIVAL(params, 26, ea_size);
     755             :         } else {
     756           0 :                 SIVAL(params, 26, 0);
     757             :         }
     758             : 
     759             :         /* Send the required number of replies */
     760           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, 30, *ppdata, 0, max_data_bytes);
     761           0 :  out:
     762           0 :         TALLOC_FREE(smb_fname);
     763           0 : }
     764             : 
     765           0 : static NTSTATUS get_lanman2_dir_entry(TALLOC_CTX *ctx,
     766             :                                 connection_struct *conn,
     767             :                                 struct dptr_struct *dirptr,
     768             :                                 uint16_t flags2,
     769             :                                 const char *path_mask,
     770             :                                 uint32_t dirtype,
     771             :                                 int info_level,
     772             :                                 bool requires_resume_key,
     773             :                                 bool dont_descend,
     774             :                                 bool ask_sharemode,
     775             :                                 char **ppdata,
     776             :                                 char *base_data,
     777             :                                 char *end_data,
     778             :                                 int space_remaining,
     779             :                                 bool *got_exact_match,
     780             :                                 int *last_entry_off,
     781             :                                 struct ea_list *name_list)
     782             : {
     783           0 :         uint8_t align = 4;
     784           0 :         const bool do_pad = true;
     785             : 
     786           0 :         if (info_level >= 1 && info_level <= 3) {
     787             :                 /* No alignment on earlier info levels. */
     788           0 :                 align = 1;
     789             :         }
     790             : 
     791           0 :         return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
     792             :                                          path_mask, dirtype, info_level,
     793             :                                          requires_resume_key, dont_descend, ask_sharemode,
     794             :                                          true, align, do_pad,
     795             :                                          ppdata, base_data, end_data,
     796             :                                          space_remaining,
     797             :                                          NULL,
     798             :                                          got_exact_match,
     799             :                                          last_entry_off, name_list, NULL);
     800             : }
     801             : 
     802             : /****************************************************************************
     803             :  Reply to a TRANS2_FINDFIRST.
     804             : ****************************************************************************/
     805             : 
     806           0 : static void call_trans2findfirst(connection_struct *conn,
     807             :                                  struct smb_request *req,
     808             :                                  char **pparams, int total_params,
     809             :                                  char **ppdata, int total_data,
     810             :                                  unsigned int max_data_bytes)
     811             : {
     812             :         /* We must be careful here that we don't return more than the
     813             :                 allowed number of data bytes. If this means returning fewer than
     814             :                 maxentries then so be it. We assume that the redirector has
     815             :                 enough room for the fixed number of parameter bytes it has
     816             :                 requested. */
     817           0 :         struct smb_filename *smb_dname = NULL;
     818           0 :         char *params = *pparams;
     819           0 :         char *pdata = *ppdata;
     820             :         char *data_end;
     821             :         uint32_t dirtype;
     822             :         int maxentries;
     823             :         uint16_t findfirst_flags;
     824             :         bool close_after_first;
     825             :         bool close_if_end;
     826             :         bool requires_resume_key;
     827             :         int info_level;
     828           0 :         char *directory = NULL;
     829           0 :         char *mask = NULL;
     830             :         char *p;
     831           0 :         int last_entry_off=0;
     832           0 :         int dptr_num = -1;
     833           0 :         int numentries = 0;
     834             :         int i;
     835           0 :         bool finished = False;
     836           0 :         bool dont_descend = False;
     837           0 :         bool out_of_space = False;
     838             :         int space_remaining;
     839           0 :         struct ea_list *ea_list = NULL;
     840           0 :         NTSTATUS ntstatus = NT_STATUS_OK;
     841           0 :         bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn));
     842           0 :         struct smbd_server_connection *sconn = req->sconn;
     843           0 :         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
     844           0 :         bool backup_priv = false;
     845           0 :         bool as_root = false;
     846           0 :         files_struct *fsp = NULL;
     847           0 :         struct files_struct *dirfsp = NULL;
     848           0 :         const struct loadparm_substitution *lp_sub =
     849           0 :                 loadparm_s3_global_substitution();
     850             : 
     851           0 :         if (total_params < 13) {
     852           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     853           0 :                 goto out;
     854             :         }
     855             : 
     856           0 :         dirtype = SVAL(params,0);
     857           0 :         maxentries = SVAL(params,2);
     858           0 :         findfirst_flags = SVAL(params,4);
     859           0 :         close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
     860           0 :         close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
     861           0 :         requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
     862           0 :         backup_priv = ((findfirst_flags & FLAG_TRANS2_FIND_BACKUP_INTENT) &&
     863           0 :                                 security_token_has_privilege(get_current_nttok(conn),
     864             :                                                 SEC_PRIV_BACKUP));
     865             : 
     866           0 :         info_level = SVAL(params,6);
     867             : 
     868           0 :         DBG_NOTICE("dirtype = %"PRIx32", maxentries = %d, "
     869             :                    "close_after_first=%d, close_if_end = %d "
     870             :                    "requires_resume_key = %d backup_priv = %d level = 0x%x, "
     871             :                    "max_data_bytes = %d\n",
     872             :                    dirtype,
     873             :                    maxentries,
     874             :                    close_after_first,
     875             :                    close_if_end,
     876             :                    requires_resume_key,
     877             :                    backup_priv,
     878             :                    info_level,
     879             :                    max_data_bytes);
     880             : 
     881           0 :         if (!maxentries) {
     882             :                 /* W2K3 seems to treat zero as 1. */
     883           0 :                 maxentries = 1;
     884             :         }
     885             : 
     886           0 :         switch (info_level) {
     887           0 :                 case SMB_FIND_INFO_STANDARD:
     888             :                 case SMB_FIND_EA_SIZE:
     889             :                 case SMB_FIND_EA_LIST:
     890             :                 case SMB_FIND_FILE_DIRECTORY_INFO:
     891             :                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
     892             :                 case SMB_FIND_FILE_NAMES_INFO:
     893             :                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
     894             :                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
     895             :                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
     896           0 :                         break;
     897           0 :                 case SMB_FIND_FILE_UNIX:
     898             :                 case SMB_FIND_FILE_UNIX_INFO2:
     899           0 :                         if (!lp_smb1_unix_extensions()) {
     900           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
     901           0 :                                 goto out;
     902             :                         }
     903           0 :                         if (!req->posix_pathnames) {
     904           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
     905           0 :                                 goto out;
     906             :                         }
     907           0 :                         break;
     908           0 :                 default:
     909           0 :                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
     910           0 :                         goto out;
     911             :         }
     912             : 
     913           0 :         if (req->posix_pathnames) {
     914             :                 /* Always use filesystem for UNIX mtime query. */
     915           0 :                 ask_sharemode = false;
     916             :         }
     917             : 
     918           0 :         if (req->posix_pathnames) {
     919           0 :                 srvstr_get_path_posix(talloc_tos(),
     920             :                                 params,
     921           0 :                                 req->flags2,
     922             :                                 &directory,
     923           0 :                                 params+12,
     924           0 :                                 total_params - 12,
     925             :                                 STR_TERMINATE,
     926             :                                 &ntstatus);
     927             :         } else {
     928           0 :                 srvstr_get_path(talloc_tos(),
     929             :                                 params,
     930           0 :                                 req->flags2,
     931             :                                 &directory,
     932           0 :                                 params+12,
     933           0 :                                 total_params - 12,
     934             :                                 STR_TERMINATE,
     935             :                                 &ntstatus);
     936             :         }
     937           0 :         if (!NT_STATUS_IS_OK(ntstatus)) {
     938           0 :                 reply_nterror(req, ntstatus);
     939           0 :                 goto out;
     940             :         }
     941             : 
     942           0 :         if (backup_priv) {
     943           0 :                 become_root();
     944           0 :                 as_root = true;
     945             :         }
     946           0 :         ntstatus = filename_convert_smb1_search_path(talloc_tos(),
     947             :                                                      conn,
     948             :                                                      directory,
     949             :                                                      ucf_flags,
     950             :                                                      &dirfsp,
     951             :                                                      &smb_dname,
     952             :                                                      &mask);
     953             : 
     954           0 :         if (!NT_STATUS_IS_OK(ntstatus)) {
     955           0 :                 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
     956           0 :                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
     957             :                                         ERRSRV, ERRbadpath);
     958           0 :                         goto out;
     959             :                 }
     960           0 :                 reply_nterror(req, ntstatus);
     961           0 :                 goto out;
     962             :         }
     963             : 
     964           0 :         TALLOC_FREE(directory);
     965           0 :         directory = smb_dname->base_name;
     966             : 
     967           0 :         DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
     968             : 
     969           0 :         if (info_level == SMB_FIND_EA_LIST) {
     970             :                 uint32_t ea_size;
     971             : 
     972           0 :                 if (total_data < 4) {
     973           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     974           0 :                         goto out;
     975             :                 }
     976             : 
     977           0 :                 ea_size = IVAL(pdata,0);
     978           0 :                 if (ea_size != total_data) {
     979           0 :                         DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
     980             : total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
     981           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     982           0 :                         goto out;
     983             :                 }
     984             : 
     985           0 :                 if (!lp_ea_support(SNUM(conn))) {
     986           0 :                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
     987           0 :                         goto out;
     988             :                 }
     989             : 
     990             :                 /* Pull out the list of names. */
     991           0 :                 ea_list = read_ea_name_list(talloc_tos(), pdata + 4, ea_size - 4);
     992           0 :                 if (!ea_list) {
     993           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     994           0 :                         goto out;
     995             :                 }
     996             :         }
     997             : 
     998           0 :         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
     999           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1000           0 :                 goto out;
    1001             :         }
    1002             : 
    1003           0 :         *ppdata = (char *)SMB_REALLOC(
    1004             :                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
    1005           0 :         if(*ppdata == NULL ) {
    1006           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1007           0 :                 goto out;
    1008             :         }
    1009           0 :         pdata = *ppdata;
    1010           0 :         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
    1011             :         /*
    1012             :          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
    1013             :          * error.
    1014             :          */
    1015           0 :         memset(pdata + total_data, 0, ((max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data));
    1016             :         /* Realloc the params space */
    1017           0 :         *pparams = (char *)SMB_REALLOC(*pparams, 10);
    1018           0 :         if (*pparams == NULL) {
    1019           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1020           0 :                 goto out;
    1021             :         }
    1022           0 :         params = *pparams;
    1023             : 
    1024             :         /*
    1025             :          * Open an fsp on this directory for the dptr.
    1026             :          */
    1027           0 :         ntstatus = SMB_VFS_CREATE_FILE(
    1028             :                         conn, /* conn */
    1029             :                         req, /* req */
    1030             :                         dirfsp, /* dirfsp */
    1031             :                         smb_dname, /* dname */
    1032             :                         FILE_LIST_DIRECTORY, /* access_mask */
    1033             :                         FILE_SHARE_READ|
    1034             :                         FILE_SHARE_WRITE, /* share_access */
    1035             :                         FILE_OPEN, /* create_disposition*/
    1036             :                         FILE_DIRECTORY_FILE, /* create_options */
    1037             :                         FILE_ATTRIBUTE_DIRECTORY,/* file_attributes */
    1038             :                         NO_OPLOCK, /* oplock_request */
    1039             :                         NULL, /* lease */
    1040             :                         0, /* allocation_size */
    1041             :                         0, /* private_flags */
    1042             :                         NULL, /* sd */
    1043             :                         NULL, /* ea_list */
    1044             :                         &fsp, /* result */
    1045             :                         NULL, /* pinfo */
    1046             :                         NULL, /* in_context */
    1047             :                         NULL);/* out_context */
    1048             : 
    1049           0 :         if (!NT_STATUS_IS_OK(ntstatus)) {
    1050           0 :                 DBG_ERR("failed to open directory %s\n",
    1051             :                         smb_fname_str_dbg(smb_dname));
    1052           0 :                 reply_nterror(req, ntstatus);
    1053           0 :                 goto out;
    1054             :         }
    1055             : 
    1056             :         /* Save the wildcard match and attribs we are using on this directory -
    1057             :                 needed as lanman2 assumes these are being saved between calls */
    1058             : 
    1059           0 :         ntstatus = dptr_create(conn,
    1060             :                                 req,
    1061             :                                 fsp, /* fsp */
    1062             :                                 False,
    1063             :                                 True,
    1064           0 :                                 req->smbpid,
    1065             :                                 mask,
    1066             :                                 dirtype,
    1067           0 :                                 &fsp->dptr);
    1068             : 
    1069           0 :         if (!NT_STATUS_IS_OK(ntstatus)) {
    1070             :                 /*
    1071             :                  * Use NULL here for the first parameter (req)
    1072             :                  * as this is not a client visible handle so
    1073             :                  * can'tbe part of an SMB1 chain.
    1074             :                  */
    1075           0 :                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
    1076           0 :                 reply_nterror(req, ntstatus);
    1077           0 :                 goto out;
    1078             :         }
    1079             : 
    1080           0 :         if (backup_priv) {
    1081             :                 /* Remember this in case we have
    1082             :                    to do a findnext. */
    1083           0 :                 dptr_set_priv(fsp->dptr);
    1084             :         }
    1085             : 
    1086           0 :         dptr_num = dptr_dnum(fsp->dptr);
    1087           0 :         DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
    1088             : 
    1089             :         /* We don't need to check for VOL here as this is returned by
    1090             :                 a different TRANS2 call. */
    1091             : 
    1092           0 :         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
    1093             :                  directory,lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn))));
    1094           0 :         if (in_list(directory,
    1095           0 :                     lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn)),
    1096           0 :                         dptr_case_sensitive(fsp->dptr))) {
    1097           0 :                 dont_descend = True;
    1098             :         }
    1099             : 
    1100           0 :         p = pdata;
    1101           0 :         space_remaining = max_data_bytes;
    1102           0 :         out_of_space = False;
    1103             : 
    1104           0 :         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
    1105           0 :                 bool got_exact_match = False;
    1106             : 
    1107             :                 /* this is a heuristic to avoid seeking the dirptr except when
    1108             :                         absolutely necessary. It allows for a filename of about 40 chars */
    1109           0 :                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
    1110           0 :                         out_of_space = True;
    1111           0 :                         finished = False;
    1112             :                 } else {
    1113           0 :                         ntstatus = get_lanman2_dir_entry(talloc_tos(),
    1114             :                                         conn,
    1115           0 :                                         fsp->dptr,
    1116           0 :                                         req->flags2,
    1117             :                                         mask,dirtype,info_level,
    1118             :                                         requires_resume_key,dont_descend,
    1119             :                                         ask_sharemode,
    1120             :                                         &p,pdata,data_end,
    1121             :                                         space_remaining,
    1122             :                                         &got_exact_match,
    1123             :                                         &last_entry_off, ea_list);
    1124           0 :                         if (NT_STATUS_EQUAL(ntstatus,
    1125             :                                         NT_STATUS_ILLEGAL_CHARACTER)) {
    1126             :                                 /*
    1127             :                                  * Bad character conversion on name. Ignore this
    1128             :                                  * entry.
    1129             :                                  */
    1130           0 :                                 continue;
    1131             :                         }
    1132           0 :                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
    1133           0 :                                 out_of_space = true;
    1134             :                         } else {
    1135           0 :                                 finished = !NT_STATUS_IS_OK(ntstatus);
    1136             :                         }
    1137             :                 }
    1138             : 
    1139           0 :                 if (!finished && !out_of_space)
    1140           0 :                         numentries++;
    1141             : 
    1142             :                 /*
    1143             :                  * As an optimisation if we know we aren't looking
    1144             :                  * for a wildcard name (ie. the name matches the wildcard exactly)
    1145             :                  * then we can finish on any (first) match.
    1146             :                  * This speeds up large directory searches. JRA.
    1147             :                  */
    1148             : 
    1149           0 :                 if(got_exact_match)
    1150           0 :                         finished = True;
    1151             : 
    1152             :                 /* Ensure space_remaining never goes -ve. */
    1153           0 :                 if (PTR_DIFF(p,pdata) > max_data_bytes) {
    1154           0 :                         space_remaining = 0;
    1155           0 :                         out_of_space = true;
    1156             :                 } else {
    1157           0 :                         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
    1158             :                 }
    1159             :         }
    1160             : 
    1161             :         /* Check if we can close the dirptr */
    1162           0 :         if(close_after_first || (finished && close_if_end)) {
    1163           0 :                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
    1164           0 :                 dptr_num = -1;
    1165           0 :                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
    1166             :         }
    1167             : 
    1168             :         /*
    1169             :          * If there are no matching entries we must return ERRDOS/ERRbadfile -
    1170             :          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
    1171             :          * the protocol level is less than NT1. Tested with smbclient. JRA.
    1172             :          * This should fix the OS/2 client bug #2335.
    1173             :          */
    1174             : 
    1175           0 :         if(numentries == 0) {
    1176           0 :                 dptr_num = -1;
    1177             :                 /*
    1178             :                  * We may have already closed the file in the
    1179             :                  * close_after_first or finished case above.
    1180             :                  */
    1181           0 :                 if (fsp != NULL) {
    1182           0 :                         close_file_free(NULL, &fsp, NORMAL_CLOSE);
    1183             :                 }
    1184           0 :                 if (get_Protocol() < PROTOCOL_NT1) {
    1185           0 :                         reply_force_doserror(req, ERRDOS, ERRnofiles);
    1186           0 :                         goto out;
    1187             :                 } else {
    1188           0 :                         reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
    1189             :                                         ERRDOS, ERRbadfile);
    1190           0 :                         goto out;
    1191             :                 }
    1192             :         }
    1193             : 
    1194             :         /* At this point pdata points to numentries directory entries. */
    1195             : 
    1196             :         /* Set up the return parameter block */
    1197           0 :         SSVAL(params,0,dptr_num);
    1198           0 :         SSVAL(params,2,numentries);
    1199           0 :         SSVAL(params,4,finished);
    1200           0 :         SSVAL(params,6,0); /* Never an EA error */
    1201           0 :         SSVAL(params,8,last_entry_off);
    1202             : 
    1203           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, 10, pdata, PTR_DIFF(p,pdata),
    1204             :                             max_data_bytes);
    1205             : 
    1206           0 :         if ((! *directory) && dptr_path(sconn, dptr_num)) {
    1207           0 :                 directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
    1208           0 :                 if (!directory) {
    1209           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    1210             :                 }
    1211             :         }
    1212             : 
    1213           0 :         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
    1214             :                 smb_fn_name(req->cmd),
    1215             :                 mask, directory, dirtype, numentries ) );
    1216             : 
    1217             :         /*
    1218             :          * Force a name mangle here to ensure that the
    1219             :          * mask as an 8.3 name is top of the mangled cache.
    1220             :          * The reasons for this are subtle. Don't remove
    1221             :          * this code unless you know what you are doing
    1222             :          * (see PR#13758). JRA.
    1223             :          */
    1224             : 
    1225           0 :         if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
    1226             :                 char mangled_name[13];
    1227           0 :                 name_to_8_3(mask, mangled_name, True, conn->params);
    1228             :         }
    1229           0 :  out:
    1230             : 
    1231           0 :         if (as_root) {
    1232           0 :                 unbecome_root();
    1233             :         }
    1234             : 
    1235           0 :         TALLOC_FREE(smb_dname);
    1236           0 :         return;
    1237             : }
    1238             : 
    1239             : /****************************************************************************
    1240             :  Reply to a TRANS2_FINDNEXT.
    1241             : ****************************************************************************/
    1242             : 
    1243           0 : static void call_trans2findnext(connection_struct *conn,
    1244             :                                 struct smb_request *req,
    1245             :                                 char **pparams, int total_params,
    1246             :                                 char **ppdata, int total_data,
    1247             :                                 unsigned int max_data_bytes)
    1248             : {
    1249             :         /* We must be careful here that we don't return more than the
    1250             :                 allowed number of data bytes. If this means returning fewer than
    1251             :                 maxentries then so be it. We assume that the redirector has
    1252             :                 enough room for the fixed number of parameter bytes it has
    1253             :                 requested. */
    1254           0 :         char *params = *pparams;
    1255           0 :         char *pdata = *ppdata;
    1256             :         char *data_end;
    1257             :         int dptr_num;
    1258             :         int maxentries;
    1259             :         uint16_t info_level;
    1260             :         uint32_t resume_key;
    1261             :         uint16_t findnext_flags;
    1262             :         bool close_after_request;
    1263             :         bool close_if_end;
    1264             :         bool requires_resume_key;
    1265             :         bool continue_bit;
    1266           0 :         char *resume_name = NULL;
    1267           0 :         const char *mask = NULL;
    1268           0 :         const char *directory = NULL;
    1269           0 :         char *p = NULL;
    1270             :         uint16_t dirtype;
    1271           0 :         int numentries = 0;
    1272           0 :         int i, last_entry_off=0;
    1273           0 :         bool finished = False;
    1274           0 :         bool dont_descend = False;
    1275           0 :         bool out_of_space = False;
    1276             :         int space_remaining;
    1277           0 :         struct ea_list *ea_list = NULL;
    1278           0 :         NTSTATUS ntstatus = NT_STATUS_OK;
    1279           0 :         bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn));
    1280           0 :         TALLOC_CTX *ctx = talloc_tos();
    1281           0 :         struct smbd_server_connection *sconn = req->sconn;
    1282           0 :         bool backup_priv = false;
    1283           0 :         bool as_root = false;
    1284           0 :         files_struct *fsp = NULL;
    1285           0 :         const struct loadparm_substitution *lp_sub =
    1286           0 :                 loadparm_s3_global_substitution();
    1287             : 
    1288           0 :         if (total_params < 13) {
    1289           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1290           0 :                 return;
    1291             :         }
    1292             : 
    1293           0 :         dptr_num = SVAL(params,0);
    1294           0 :         maxentries = SVAL(params,2);
    1295           0 :         info_level = SVAL(params,4);
    1296           0 :         resume_key = IVAL(params,6);
    1297           0 :         findnext_flags = SVAL(params,10);
    1298           0 :         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
    1299           0 :         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
    1300           0 :         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
    1301           0 :         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
    1302             : 
    1303           0 :         if (!continue_bit) {
    1304             :                 /* We only need resume_name if continue_bit is zero. */
    1305           0 :                 if (req->posix_pathnames) {
    1306           0 :                         srvstr_get_path_posix(ctx,
    1307             :                                 params,
    1308           0 :                                 req->flags2,
    1309             :                                 &resume_name,
    1310           0 :                                 params+12,
    1311           0 :                                 total_params - 12,
    1312             :                                 STR_TERMINATE,
    1313             :                                 &ntstatus);
    1314             :                 } else {
    1315           0 :                         srvstr_get_path(ctx,
    1316             :                                 params,
    1317           0 :                                 req->flags2,
    1318             :                                 &resume_name,
    1319           0 :                                 params+12,
    1320           0 :                                 total_params - 12,
    1321             :                                 STR_TERMINATE,
    1322             :                                 &ntstatus);
    1323             :                 }
    1324           0 :                 if (!NT_STATUS_IS_OK(ntstatus)) {
    1325             :                         /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
    1326             :                            complain (it thinks we're asking for the directory above the shared
    1327             :                            path or an invalid name). Catch this as the resume name is only compared, never used in
    1328             :                            a file access. JRA. */
    1329           0 :                         srvstr_pull_talloc(ctx, params, req->flags2,
    1330             :                                 &resume_name, params+12,
    1331             :                                 total_params - 12,
    1332             :                                 STR_TERMINATE);
    1333             : 
    1334           0 :                         if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
    1335           0 :                                 reply_nterror(req, ntstatus);
    1336           0 :                                 return;
    1337             :                         }
    1338             :                 }
    1339             :         }
    1340             : 
    1341           0 :         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
    1342             : close_after_request=%d, close_if_end = %d requires_resume_key = %d \
    1343             : resume_key = %d resume name = %s continue=%d level = %d\n",
    1344             :                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
    1345             :                 requires_resume_key, resume_key,
    1346             :                 resume_name ? resume_name : "(NULL)", continue_bit, info_level));
    1347             : 
    1348           0 :         if (!maxentries) {
    1349             :                 /* W2K3 seems to treat zero as 1. */
    1350           0 :                 maxentries = 1;
    1351             :         }
    1352             : 
    1353           0 :         switch (info_level) {
    1354           0 :                 case SMB_FIND_INFO_STANDARD:
    1355             :                 case SMB_FIND_EA_SIZE:
    1356             :                 case SMB_FIND_EA_LIST:
    1357             :                 case SMB_FIND_FILE_DIRECTORY_INFO:
    1358             :                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
    1359             :                 case SMB_FIND_FILE_NAMES_INFO:
    1360             :                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
    1361             :                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
    1362             :                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
    1363           0 :                         break;
    1364           0 :                 case SMB_FIND_FILE_UNIX:
    1365             :                 case SMB_FIND_FILE_UNIX_INFO2:
    1366             :                         /* Always use filesystem for UNIX mtime query. */
    1367           0 :                         ask_sharemode = false;
    1368           0 :                         if (!lp_smb1_unix_extensions()) {
    1369           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    1370           0 :                                 return;
    1371             :                         }
    1372           0 :                         if (!req->posix_pathnames) {
    1373           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    1374           0 :                                 return;
    1375             :                         }
    1376           0 :                         break;
    1377           0 :                 default:
    1378           0 :                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    1379           0 :                         return;
    1380             :         }
    1381             : 
    1382           0 :         if (info_level == SMB_FIND_EA_LIST) {
    1383             :                 uint32_t ea_size;
    1384             : 
    1385           0 :                 if (total_data < 4) {
    1386           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1387           0 :                         return;
    1388             :                 }
    1389             : 
    1390           0 :                 ea_size = IVAL(pdata,0);
    1391           0 :                 if (ea_size != total_data) {
    1392           0 :                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
    1393             : total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
    1394           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1395           0 :                         return;
    1396             :                 }
    1397             : 
    1398           0 :                 if (!lp_ea_support(SNUM(conn))) {
    1399           0 :                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
    1400           0 :                         return;
    1401             :                 }
    1402             : 
    1403             :                 /* Pull out the list of names. */
    1404           0 :                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
    1405           0 :                 if (!ea_list) {
    1406           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1407           0 :                         return;
    1408             :                 }
    1409             :         }
    1410             : 
    1411           0 :         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
    1412           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1413           0 :                 return;
    1414             :         }
    1415             : 
    1416           0 :         *ppdata = (char *)SMB_REALLOC(
    1417             :                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
    1418           0 :         if(*ppdata == NULL) {
    1419           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1420           0 :                 return;
    1421             :         }
    1422             : 
    1423           0 :         pdata = *ppdata;
    1424           0 :         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
    1425             : 
    1426             :         /*
    1427             :          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
    1428             :          * error.
    1429             :          */
    1430           0 :         memset(pdata + total_data, 0, (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data);
    1431             :         /* Realloc the params space */
    1432           0 :         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
    1433           0 :         if(*pparams == NULL ) {
    1434           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1435           0 :                 return;
    1436             :         }
    1437             : 
    1438           0 :         params = *pparams;
    1439             : 
    1440             :         /* Check that the dptr is valid */
    1441           0 :         fsp = dptr_fetch_lanman2_fsp(sconn, dptr_num);
    1442           0 :         if (fsp == NULL) {
    1443           0 :                 reply_nterror(req, STATUS_NO_MORE_FILES);
    1444           0 :                 return;
    1445             :         }
    1446             : 
    1447           0 :         directory = dptr_path(sconn, dptr_num);
    1448             : 
    1449             :         /* Get the wildcard mask from the dptr */
    1450           0 :         if((mask = dptr_wcard(sconn, dptr_num))== NULL) {
    1451           0 :                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
    1452           0 :                 reply_nterror(req, STATUS_NO_MORE_FILES);
    1453           0 :                 return;
    1454             :         }
    1455             : 
    1456             :         /* Get the attr mask from the dptr */
    1457           0 :         dirtype = dptr_attr(sconn, dptr_num);
    1458             : 
    1459           0 :         backup_priv = dptr_get_priv(fsp->dptr);
    1460             : 
    1461           0 :         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
    1462             :                 "backup_priv = %d\n",
    1463             :                 dptr_num, mask, dirtype,
    1464             :                 (long)fsp->dptr,
    1465             :                 dptr_TellDir(fsp->dptr),
    1466             :                 (int)backup_priv));
    1467             : 
    1468             :         /* We don't need to check for VOL here as this is returned by
    1469             :                 a different TRANS2 call. */
    1470             : 
    1471           0 :         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
    1472             :                  directory,lp_dont_descend(ctx, lp_sub, SNUM(conn))));
    1473           0 :         if (in_list(directory,lp_dont_descend(ctx, lp_sub, SNUM(conn)),
    1474           0 :                         dptr_case_sensitive(fsp->dptr)))
    1475           0 :                 dont_descend = True;
    1476             : 
    1477           0 :         p = pdata;
    1478           0 :         space_remaining = max_data_bytes;
    1479           0 :         out_of_space = False;
    1480             : 
    1481           0 :         if (backup_priv) {
    1482           0 :                 become_root();
    1483           0 :                 as_root = true;
    1484             :         }
    1485             : 
    1486             :         /*
    1487             :          * Seek to the correct position. We no longer use the resume key but
    1488             :          * depend on the last file name instead.
    1489             :          */
    1490             : 
    1491           0 :         if(!continue_bit && resume_name && *resume_name) {
    1492             :                 SMB_STRUCT_STAT st;
    1493           0 :                 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
    1494             : 
    1495           0 :                 long current_pos = 0;
    1496             :                 /*
    1497             :                  * Remember, name_to_8_3 is called by
    1498             :                  * get_lanman2_dir_entry(), so the resume name
    1499             :                  * could be mangled. Ensure we check the unmangled name.
    1500             :                  */
    1501             : 
    1502           0 :                 if (!posix_open &&
    1503           0 :                                 mangle_is_mangled(resume_name, conn->params)) {
    1504           0 :                         char *new_resume_name = NULL;
    1505           0 :                         mangle_lookup_name_from_8_3(ctx,
    1506             :                                                 resume_name,
    1507             :                                                 &new_resume_name,
    1508           0 :                                                 conn->params);
    1509           0 :                         if (new_resume_name) {
    1510           0 :                                 resume_name = new_resume_name;
    1511             :                         }
    1512             :                 }
    1513             : 
    1514             :                 /*
    1515             :                  * Fix for NT redirector problem triggered by resume key indexes
    1516             :                  * changing between directory scans. We now return a resume key of 0
    1517             :                  * and instead look for the filename to continue from (also given
    1518             :                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
    1519             :                  * findfirst/findnext (as is usual) then the directory pointer
    1520             :                  * should already be at the correct place.
    1521             :                  */
    1522             : 
    1523           0 :                 finished = !dptr_SearchDir(fsp->dptr, resume_name, &current_pos, &st);
    1524             :         } /* end if resume_name && !continue_bit */
    1525             : 
    1526           0 :         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
    1527           0 :                 bool got_exact_match = False;
    1528             : 
    1529             :                 /* this is a heuristic to avoid seeking the fsp->dptr except when
    1530             :                         absolutely necessary. It allows for a filename of about 40 chars */
    1531           0 :                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
    1532           0 :                         out_of_space = True;
    1533           0 :                         finished = False;
    1534             :                 } else {
    1535           0 :                         ntstatus = get_lanman2_dir_entry(ctx,
    1536             :                                                 conn,
    1537           0 :                                                 fsp->dptr,
    1538           0 :                                                 req->flags2,
    1539             :                                                 mask,dirtype,info_level,
    1540             :                                                 requires_resume_key,dont_descend,
    1541             :                                                 ask_sharemode,
    1542             :                                                 &p,pdata,data_end,
    1543             :                                                 space_remaining,
    1544             :                                                 &got_exact_match,
    1545             :                                                 &last_entry_off, ea_list);
    1546           0 :                         if (NT_STATUS_EQUAL(ntstatus,
    1547             :                                         NT_STATUS_ILLEGAL_CHARACTER)) {
    1548             :                                 /*
    1549             :                                  * Bad character conversion on name. Ignore this
    1550             :                                  * entry.
    1551             :                                  */
    1552           0 :                                 continue;
    1553             :                         }
    1554           0 :                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
    1555           0 :                                 out_of_space = true;
    1556             :                         } else {
    1557           0 :                                 finished = !NT_STATUS_IS_OK(ntstatus);
    1558             :                         }
    1559             :                 }
    1560             : 
    1561           0 :                 if (!finished && !out_of_space)
    1562           0 :                         numentries++;
    1563             : 
    1564             :                 /*
    1565             :                  * As an optimisation if we know we aren't looking
    1566             :                  * for a wildcard name (ie. the name matches the wildcard exactly)
    1567             :                  * then we can finish on any (first) match.
    1568             :                  * This speeds up large directory searches. JRA.
    1569             :                  */
    1570             : 
    1571           0 :                 if(got_exact_match)
    1572           0 :                         finished = True;
    1573             : 
    1574           0 :                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
    1575             :         }
    1576             : 
    1577           0 :         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
    1578             :                 smb_fn_name(req->cmd),
    1579             :                 mask, directory, dirtype, numentries ) );
    1580             : 
    1581             :         /* Check if we can close the fsp->dptr */
    1582           0 :         if(close_after_request || (finished && close_if_end)) {
    1583           0 :                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
    1584           0 :                 dptr_num = -1;
    1585           0 :                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
    1586             :         }
    1587             : 
    1588           0 :         if (as_root) {
    1589           0 :                 unbecome_root();
    1590             :         }
    1591             : 
    1592             :         /* Set up the return parameter block */
    1593           0 :         SSVAL(params,0,numentries);
    1594           0 :         SSVAL(params,2,finished);
    1595           0 :         SSVAL(params,4,0); /* Never an EA error */
    1596           0 :         SSVAL(params,6,last_entry_off);
    1597             : 
    1598           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, 8, pdata, PTR_DIFF(p,pdata),
    1599             :                             max_data_bytes);
    1600             : 
    1601           0 :         return;
    1602             : }
    1603             : 
    1604             : /****************************************************************************
    1605             :  Reply to a TRANS2_QFSINFO (query filesystem info).
    1606             : ****************************************************************************/
    1607             : 
    1608           8 : static void call_trans2qfsinfo(connection_struct *conn,
    1609             :                                struct smb_request *req,
    1610             :                                char **pparams, int total_params,
    1611             :                                char **ppdata, int total_data,
    1612             :                                unsigned int max_data_bytes)
    1613             : {
    1614           8 :         char *params = *pparams;
    1615             :         uint16_t info_level;
    1616           8 :         int data_len = 0;
    1617             :         size_t fixed_portion;
    1618             :         NTSTATUS status;
    1619             : 
    1620           8 :         if (total_params < 2) {
    1621           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1622           0 :                 return;
    1623             :         }
    1624             : 
    1625           8 :         info_level = SVAL(params,0);
    1626             : 
    1627           8 :         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
    1628           0 :                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
    1629           0 :                         DEBUG(0,("call_trans2qfsinfo: encryption required "
    1630             :                                 "and info level 0x%x sent.\n",
    1631             :                                 (unsigned int)info_level));
    1632           0 :                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1633           0 :                         return;
    1634             :                 }
    1635             :         }
    1636             : 
    1637           8 :         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
    1638             : 
    1639           8 :         status = smbd_do_qfsinfo(req->xconn, conn, req,
    1640             :                                  info_level,
    1641           8 :                                  req->flags2,
    1642             :                                  max_data_bytes,
    1643             :                                  &fixed_portion,
    1644             :                                  NULL,
    1645             :                                  ppdata, &data_len);
    1646           8 :         if (!NT_STATUS_IS_OK(status)) {
    1647           0 :                 reply_nterror(req, status);
    1648           0 :                 return;
    1649             :         }
    1650             : 
    1651           8 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, 0, *ppdata, data_len,
    1652             :                             max_data_bytes);
    1653             : 
    1654           8 :         DEBUG( 4, ( "%s info_level = %d\n",
    1655             :                     smb_fn_name(req->cmd), info_level) );
    1656             : 
    1657           8 :         return;
    1658             : }
    1659             : 
    1660             : /****************************************************************************
    1661             :  Reply to a TRANS2_SETFSINFO (set filesystem info).
    1662             : ****************************************************************************/
    1663             : 
    1664           0 : static void call_trans2setfsinfo(connection_struct *conn,
    1665             :                                  struct smb_request *req,
    1666             :                                  char **pparams, int total_params,
    1667             :                                  char **ppdata, int total_data,
    1668             :                                  unsigned int max_data_bytes)
    1669             : {
    1670           0 :         const struct loadparm_substitution *lp_sub =
    1671           0 :                 loadparm_s3_global_substitution();
    1672           0 :         struct smbXsrv_connection *xconn = req->xconn;
    1673           0 :         char *pdata = *ppdata;
    1674           0 :         char *params = *pparams;
    1675             :         uint16_t info_level;
    1676             : 
    1677           0 :         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
    1678             :                   lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
    1679             : 
    1680             :         /*  */
    1681           0 :         if (total_params < 4) {
    1682           0 :                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
    1683             :                         total_params));
    1684           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1685           0 :                 return;
    1686             :         }
    1687             : 
    1688           0 :         info_level = SVAL(params,2);
    1689             : 
    1690           0 :         if (IS_IPC(conn)) {
    1691           0 :                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
    1692             :                                 info_level != SMB_SET_CIFS_UNIX_INFO) {
    1693           0 :                         DEBUG(0,("call_trans2setfsinfo: not an allowed "
    1694             :                                 "info level (0x%x) on IPC$.\n",
    1695             :                                 (unsigned int)info_level));
    1696           0 :                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1697           0 :                         return;
    1698             :                 }
    1699             :         }
    1700             : 
    1701           0 :         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
    1702           0 :                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
    1703           0 :                         DEBUG(0,("call_trans2setfsinfo: encryption required "
    1704             :                                 "and info level 0x%x sent.\n",
    1705             :                                 (unsigned int)info_level));
    1706           0 :                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1707           0 :                         return;
    1708             :                 }
    1709             :         }
    1710             : 
    1711           0 :         switch(info_level) {
    1712           0 :                 case SMB_SET_CIFS_UNIX_INFO:
    1713           0 :                         if (!lp_smb1_unix_extensions()) {
    1714           0 :                                 DEBUG(2,("call_trans2setfsinfo: "
    1715             :                                         "SMB_SET_CIFS_UNIX_INFO is invalid with "
    1716             :                                         "unix extensions off\n"));
    1717           0 :                                 reply_nterror(req,
    1718             :                                               NT_STATUS_INVALID_LEVEL);
    1719           0 :                                 return;
    1720             :                         }
    1721             : 
    1722             :                         /* There should be 12 bytes of capabilities set. */
    1723           0 :                         if (total_data < 12) {
    1724           0 :                                 reply_nterror(
    1725             :                                         req,
    1726             :                                         NT_STATUS_INVALID_PARAMETER);
    1727           0 :                                 return;
    1728             :                         }
    1729           0 :                         xconn->smb1.unix_info.client_major = SVAL(pdata,0);
    1730           0 :                         xconn->smb1.unix_info.client_minor = SVAL(pdata,2);
    1731           0 :                         xconn->smb1.unix_info.client_cap_low = IVAL(pdata,4);
    1732           0 :                         xconn->smb1.unix_info.client_cap_high = IVAL(pdata,8);
    1733             :                         /* Just print these values for now. */
    1734           0 :                         DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
    1735             :                                    "major = %u, minor = %u cap_low = 0x%x, "
    1736             :                                    "cap_high = 0x%xn",
    1737             :                                    (unsigned int)xconn->
    1738             :                                    smb1.unix_info.client_major,
    1739             :                                    (unsigned int)xconn->
    1740             :                                    smb1.unix_info.client_minor,
    1741             :                                    (unsigned int)xconn->
    1742             :                                    smb1.unix_info.client_cap_low,
    1743             :                                    (unsigned int)xconn->
    1744             :                                    smb1.unix_info.client_cap_high));
    1745             : 
    1746             :                         /* Here is where we must switch to posix pathname processing... */
    1747           0 :                         if (xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
    1748           0 :                                 lp_set_posix_pathnames();
    1749           0 :                                 mangle_change_to_posix();
    1750             :                         }
    1751             : 
    1752           0 :                         if ((xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
    1753           0 :                             !(xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
    1754             :                                 /* Client that knows how to do posix locks,
    1755             :                                  * but not posix open/mkdir operations. Set a
    1756             :                                  * default type for read/write checks. */
    1757             : 
    1758           0 :                                 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
    1759             : 
    1760             :                         }
    1761           0 :                         break;
    1762             : 
    1763           0 :                 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
    1764             :                         {
    1765             :                                 NTSTATUS status;
    1766           0 :                                 size_t param_len = 0;
    1767           0 :                                 size_t data_len = total_data;
    1768             : 
    1769           0 :                                 if (!lp_smb1_unix_extensions()) {
    1770           0 :                                         reply_nterror(
    1771             :                                                 req,
    1772             :                                                 NT_STATUS_INVALID_LEVEL);
    1773           0 :                                         return;
    1774             :                                 }
    1775             : 
    1776           0 :                                 if (lp_server_smb_encrypt(SNUM(conn)) ==
    1777             :                                     SMB_ENCRYPTION_OFF) {
    1778           0 :                                         reply_nterror(
    1779             :                                                 req,
    1780             :                                                 NT_STATUS_NOT_SUPPORTED);
    1781           0 :                                         return;
    1782             :                                 }
    1783             : 
    1784           0 :                                 if (xconn->smb1.echo_handler.trusted_fde) {
    1785           0 :                                         DEBUG( 2,("call_trans2setfsinfo: "
    1786             :                                                 "request transport encryption disabled"
    1787             :                                                 "with 'fork echo handler = yes'\n"));
    1788           0 :                                         reply_nterror(
    1789             :                                                 req,
    1790             :                                                 NT_STATUS_NOT_SUPPORTED);
    1791           0 :                                         return;
    1792             :                                 }
    1793             : 
    1794           0 :                                 DEBUG( 4,("call_trans2setfsinfo: "
    1795             :                                         "request transport encryption.\n"));
    1796             : 
    1797           0 :                                 status = srv_request_encryption_setup(conn,
    1798             :                                                                 (unsigned char **)ppdata,
    1799             :                                                                 &data_len,
    1800             :                                                                 (unsigned char **)pparams,
    1801             :                                                                 &param_len);
    1802             : 
    1803           0 :                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
    1804           0 :                                                 !NT_STATUS_IS_OK(status)) {
    1805           0 :                                         reply_nterror(req, status);
    1806           0 :                                         return;
    1807             :                                 }
    1808             : 
    1809           0 :                                 send_trans2_replies(conn, req,
    1810           0 :                                                 NT_STATUS_OK,
    1811             :                                                 *pparams,
    1812             :                                                 param_len,
    1813             :                                                 *ppdata,
    1814             :                                                 data_len,
    1815             :                                                 max_data_bytes);
    1816             : 
    1817           0 :                                 if (NT_STATUS_IS_OK(status)) {
    1818             :                                         /* Server-side transport
    1819             :                                          * encryption is now *on*. */
    1820           0 :                                         status = srv_encryption_start(conn);
    1821           0 :                                         if (!NT_STATUS_IS_OK(status)) {
    1822           0 :                                                 char *reason = talloc_asprintf(talloc_tos(),
    1823             :                                                                                "Failure in setting "
    1824             :                                                                                "up encrypted transport: %s",
    1825             :                                                                                nt_errstr(status));
    1826           0 :                                                 exit_server_cleanly(reason);
    1827             :                                         }
    1828             :                                 }
    1829           0 :                                 return;
    1830             :                         }
    1831             : 
    1832           0 :                 case SMB_FS_QUOTA_INFORMATION:
    1833             :                         {
    1834             :                                 NTSTATUS status;
    1835           0 :                                 DATA_BLOB qdata = {
    1836             :                                                 .data = (uint8_t *)pdata,
    1837             :                                                 .length = total_data
    1838             :                                 };
    1839           0 :                                 files_struct *fsp = NULL;
    1840           0 :                                 fsp = file_fsp(req, SVAL(params,0));
    1841             : 
    1842           0 :                                 status = smb_set_fsquota(conn,
    1843             :                                                         req,
    1844             :                                                         fsp,
    1845             :                                                         &qdata);
    1846           0 :                                 if (!NT_STATUS_IS_OK(status)) {
    1847           0 :                                         reply_nterror(req, status);
    1848           0 :                                         return;
    1849             :                                 }
    1850           0 :                                 break;
    1851             :                         }
    1852           0 :                 default:
    1853           0 :                         DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
    1854             :                                 info_level));
    1855           0 :                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    1856           0 :                         return;
    1857             :                         break;
    1858             :         }
    1859             : 
    1860             :         /*
    1861             :          * sending this reply works fine,
    1862             :          * but I'm not sure it's the same
    1863             :          * like windows do...
    1864             :          * --metze
    1865             :          */
    1866           0 :         reply_smb1_outbuf(req, 10, 0);
    1867             : }
    1868             : 
    1869             : /****************************************************************************
    1870             :  Reply to a TRANSACT2_QFILEINFO on a PIPE !
    1871             : ****************************************************************************/
    1872             : 
    1873           0 : static void call_trans2qpipeinfo(connection_struct *conn,
    1874             :                                  struct smb_request *req,
    1875             :                                  files_struct *fsp,
    1876             :                                  uint16_t info_level,
    1877             :                                  unsigned int tran_call,
    1878             :                                  char **pparams, int total_params,
    1879             :                                  char **ppdata, int total_data,
    1880             :                                  unsigned int max_data_bytes)
    1881             : {
    1882           0 :         char *params = *pparams;
    1883           0 :         char *pdata = *ppdata;
    1884           0 :         unsigned int data_size = 0;
    1885           0 :         unsigned int param_size = 2;
    1886             : 
    1887           0 :         if (!fsp_is_np(fsp)) {
    1888           0 :                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    1889           0 :                 return;
    1890             :         }
    1891             : 
    1892           0 :         *pparams = (char *)SMB_REALLOC(*pparams,2);
    1893           0 :         if (*pparams == NULL) {
    1894           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1895           0 :                 return;
    1896             :         }
    1897           0 :         params = *pparams;
    1898           0 :         SSVAL(params,0,0);
    1899           0 :         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
    1900           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1901           0 :                 return;
    1902             :         }
    1903           0 :         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
    1904           0 :         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
    1905           0 :         if (*ppdata == NULL ) {
    1906           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1907           0 :                 return;
    1908             :         }
    1909           0 :         pdata = *ppdata;
    1910             : 
    1911           0 :         switch (info_level) {
    1912           0 :                 case SMB_FILE_STANDARD_INFORMATION:
    1913           0 :                         memset(pdata,0,24);
    1914           0 :                         SOFF_T(pdata,0,4096LL);
    1915           0 :                         SIVAL(pdata,16,1);
    1916           0 :                         SIVAL(pdata,20,1);
    1917           0 :                         data_size = 24;
    1918           0 :                         break;
    1919             : 
    1920           0 :                 default:
    1921           0 :                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    1922           0 :                         return;
    1923             :         }
    1924             : 
    1925           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
    1926             :                             max_data_bytes);
    1927             : 
    1928           0 :         return;
    1929             : }
    1930             : 
    1931             : /****************************************************************************
    1932             :  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
    1933             :  file name or file id).
    1934             : ****************************************************************************/
    1935             : 
    1936           0 : static void call_trans2qfilepathinfo(connection_struct *conn,
    1937             :                                      struct smb_request *req,
    1938             :                                      unsigned int tran_call,
    1939             :                                      char **pparams, int total_params,
    1940             :                                      char **ppdata, int total_data,
    1941             :                                      unsigned int max_data_bytes)
    1942             : {
    1943           0 :         char *params = *pparams;
    1944           0 :         char *pdata = *ppdata;
    1945             :         uint16_t info_level;
    1946           0 :         unsigned int data_size = 0;
    1947           0 :         unsigned int param_size = 2;
    1948           0 :         struct smb_filename *smb_fname = NULL;
    1949           0 :         bool delete_pending = False;
    1950             :         struct timespec write_time_ts;
    1951           0 :         struct files_struct *dirfsp = NULL;
    1952           0 :         files_struct *fsp = NULL;
    1953             :         struct file_id fileid;
    1954           0 :         struct ea_list *ea_list = NULL;
    1955           0 :         int lock_data_count = 0;
    1956           0 :         char *lock_data = NULL;
    1957             :         size_t fixed_portion;
    1958           0 :         NTSTATUS status = NT_STATUS_OK;
    1959             :         int ret;
    1960             : 
    1961           0 :         if (!params) {
    1962           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1963           0 :                 return;
    1964             :         }
    1965             : 
    1966           0 :         ZERO_STRUCT(write_time_ts);
    1967             : 
    1968           0 :         if (tran_call == TRANSACT2_QFILEINFO) {
    1969           0 :                 if (total_params < 4) {
    1970           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1971           0 :                         return;
    1972             :                 }
    1973             : 
    1974           0 :                 fsp = file_fsp(req, SVAL(params,0));
    1975           0 :                 info_level = SVAL(params,2);
    1976             : 
    1977           0 :                 if (IS_IPC(conn)) {
    1978           0 :                         call_trans2qpipeinfo(
    1979             :                                 conn,
    1980             :                                 req,
    1981             :                                 fsp,
    1982             :                                 info_level,
    1983             :                                 tran_call,
    1984             :                                 pparams,
    1985             :                                 total_params,
    1986             :                                 ppdata,
    1987             :                                 total_data,
    1988             :                                 max_data_bytes);
    1989           0 :                         return;
    1990             :                 }
    1991             : 
    1992           0 :                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
    1993             : 
    1994           0 :                 if (INFO_LEVEL_IS_UNIX(info_level)) {
    1995           0 :                         if (!lp_smb1_unix_extensions()) {
    1996           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    1997           0 :                                 return;
    1998             :                         }
    1999           0 :                         if (!req->posix_pathnames) {
    2000           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2001           0 :                                 return;
    2002             :                         }
    2003             :                 }
    2004             : 
    2005             :                 /* Initial check for valid fsp ptr. */
    2006           0 :                 if (!check_fsp_open(conn, req, fsp)) {
    2007           0 :                         return;
    2008             :                 }
    2009             : 
    2010           0 :                 smb_fname = fsp->fsp_name;
    2011             : 
    2012           0 :                 if(fsp->fake_file_handle) {
    2013             :                         /*
    2014             :                          * This is actually for the QUOTA_FAKE_FILE --metze
    2015             :                          */
    2016             : 
    2017             :                         /* We know this name is ok, it's already passed the checks. */
    2018             : 
    2019           0 :                 } else if(fsp_get_pathref_fd(fsp) == -1) {
    2020             :                         /*
    2021             :                          * This is actually a QFILEINFO on a directory
    2022             :                          * handle (returned from an NT SMB). NT5.0 seems
    2023             :                          * to do this call. JRA.
    2024             :                          */
    2025           0 :                         ret = vfs_stat(conn, smb_fname);
    2026           0 :                         if (ret != 0) {
    2027           0 :                                 DBG_NOTICE("vfs_stat of %s failed (%s)\n",
    2028             :                                          smb_fname_str_dbg(smb_fname),
    2029             :                                          strerror(errno));
    2030           0 :                                 reply_nterror(req,
    2031             :                                         map_nt_error_from_unix(errno));
    2032           0 :                                 return;
    2033             :                         }
    2034             : 
    2035           0 :                         if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
    2036           0 :                                 fileid = vfs_file_id_from_sbuf(
    2037           0 :                                         conn, &smb_fname->st);
    2038           0 :                                 get_file_infos(fileid, fsp->name_hash,
    2039             :                                                &delete_pending,
    2040             :                                                &write_time_ts);
    2041             :                         }
    2042             :                 } else {
    2043             :                         /*
    2044             :                          * Original code - this is an open file.
    2045             :                          */
    2046           0 :                         status = vfs_stat_fsp(fsp);
    2047           0 :                         if (!NT_STATUS_IS_OK(status)) {
    2048           0 :                                 DEBUG(3, ("fstat of %s failed (%s)\n",
    2049             :                                           fsp_fnum_dbg(fsp), nt_errstr(status)));
    2050           0 :                                 reply_nterror(req, status);
    2051           0 :                                 return;
    2052             :                         }
    2053           0 :                         if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
    2054           0 :                                 fileid = vfs_file_id_from_sbuf(
    2055           0 :                                         conn, &smb_fname->st);
    2056           0 :                                 get_file_infos(fileid, fsp->name_hash,
    2057             :                                                &delete_pending,
    2058             :                                                &write_time_ts);
    2059             :                         }
    2060             :                 }
    2061             : 
    2062             :         } else {
    2063             :                 uint32_t name_hash;
    2064           0 :                 char *fname = NULL;
    2065           0 :                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
    2066           0 :                 NTTIME twrp = 0;
    2067             : 
    2068             :                 /* qpathinfo */
    2069           0 :                 if (total_params < 7) {
    2070           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2071           0 :                         return;
    2072             :                 }
    2073             : 
    2074           0 :                 info_level = SVAL(params,0);
    2075             : 
    2076           0 :                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
    2077             : 
    2078           0 :                 if (INFO_LEVEL_IS_UNIX(info_level)) {
    2079           0 :                         if (!lp_smb1_unix_extensions()) {
    2080           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2081           0 :                                 return;
    2082             :                         }
    2083           0 :                         if (!req->posix_pathnames) {
    2084           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2085           0 :                                 return;
    2086             :                         }
    2087             :                 }
    2088             : 
    2089           0 :                 if (req->posix_pathnames) {
    2090           0 :                         srvstr_get_path_posix(req,
    2091             :                                 params,
    2092           0 :                                 req->flags2,
    2093             :                                 &fname,
    2094           0 :                                 &params[6],
    2095           0 :                                 total_params - 6,
    2096             :                                 STR_TERMINATE,
    2097             :                                 &status);
    2098             :                 } else {
    2099           0 :                         srvstr_get_path(req,
    2100             :                                 params,
    2101           0 :                                 req->flags2,
    2102             :                                 &fname,
    2103           0 :                                 &params[6],
    2104           0 :                                 total_params - 6,
    2105             :                                 STR_TERMINATE,
    2106             :                                 &status);
    2107             :                 }
    2108           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2109           0 :                         reply_nterror(req, status);
    2110           0 :                         return;
    2111             :                 }
    2112             : 
    2113           0 :                 if (ucf_flags & UCF_GMT_PATHNAME) {
    2114           0 :                         extract_snapshot_token(fname, &twrp);
    2115             :                 }
    2116           0 :                 status = filename_convert_dirfsp(req,
    2117             :                                                  conn,
    2118             :                                                  fname,
    2119             :                                                  ucf_flags,
    2120             :                                                  twrp,
    2121             :                                                  &dirfsp,
    2122             :                                                  &smb_fname);
    2123           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2124           0 :                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
    2125           0 :                                 reply_botherror(req,
    2126             :                                                 NT_STATUS_PATH_NOT_COVERED,
    2127             :                                                 ERRSRV, ERRbadpath);
    2128           0 :                                 return;
    2129             :                         }
    2130           0 :                         reply_nterror(req, status);
    2131           0 :                         return;
    2132             :                 }
    2133             : 
    2134             :                 /*
    2135             :                  * qpathinfo must operate on an existing file, so we
    2136             :                  * can exit early if filename_convert_dirfsp() returned the
    2137             :                  * "new file" NT_STATUS_OK, !VALID_STAT case.
    2138             :                  */
    2139             : 
    2140           0 :                 if (!VALID_STAT(smb_fname->st)) {
    2141           0 :                         reply_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    2142           0 :                         return;
    2143             :                 }
    2144             : 
    2145             :                 /*
    2146             :                  * smb_fname->fsp may be NULL if smb_fname points at a symlink
    2147             :                  * and we're in POSIX context, so be careful when using fsp
    2148             :                  * below, it can still be NULL.
    2149             :                  */
    2150           0 :                 fsp = smb_fname->fsp;
    2151             : 
    2152             :                 /* If this is a stream, check if there is a delete_pending. */
    2153           0 :                 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
    2154           0 :                     && is_ntfs_stream_smb_fname(smb_fname)) {
    2155             :                         struct smb_filename *smb_fname_base;
    2156             : 
    2157             :                         /* Create an smb_filename with stream_name == NULL. */
    2158           0 :                         smb_fname_base = synthetic_smb_fname(
    2159             :                                                 talloc_tos(),
    2160           0 :                                                 smb_fname->base_name,
    2161             :                                                 NULL,
    2162             :                                                 NULL,
    2163           0 :                                                 smb_fname->twrp,
    2164           0 :                                                 smb_fname->flags);
    2165           0 :                         if (smb_fname_base == NULL) {
    2166           0 :                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2167           0 :                                 return;
    2168             :                         }
    2169             : 
    2170           0 :                         ret = vfs_stat(conn, smb_fname_base);
    2171           0 :                         if (ret != 0) {
    2172           0 :                                 DBG_NOTICE("vfs_stat of %s failed "
    2173             :                                         "(%s)\n",
    2174             :                                         smb_fname_str_dbg(smb_fname_base),
    2175             :                                         strerror(errno));
    2176           0 :                                 TALLOC_FREE(smb_fname_base);
    2177           0 :                                 reply_nterror(req,
    2178             :                                         map_nt_error_from_unix(errno));
    2179           0 :                                 return;
    2180             :                         }
    2181             : 
    2182           0 :                         status = file_name_hash(conn,
    2183             :                                         smb_fname_str_dbg(smb_fname_base),
    2184             :                                         &name_hash);
    2185           0 :                         if (!NT_STATUS_IS_OK(status)) {
    2186           0 :                                 TALLOC_FREE(smb_fname_base);
    2187           0 :                                 reply_nterror(req, status);
    2188           0 :                                 return;
    2189             :                         }
    2190             : 
    2191           0 :                         fileid = vfs_file_id_from_sbuf(conn,
    2192           0 :                                                        &smb_fname_base->st);
    2193           0 :                         TALLOC_FREE(smb_fname_base);
    2194           0 :                         get_file_infos(fileid, name_hash, &delete_pending, NULL);
    2195           0 :                         if (delete_pending) {
    2196           0 :                                 reply_nterror(req, NT_STATUS_DELETE_PENDING);
    2197           0 :                                 return;
    2198             :                         }
    2199             :                 }
    2200             : 
    2201           0 :                 status = file_name_hash(conn,
    2202             :                                 smb_fname_str_dbg(smb_fname),
    2203             :                                 &name_hash);
    2204           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2205           0 :                         reply_nterror(req, status);
    2206           0 :                         return;
    2207             :                 }
    2208             : 
    2209           0 :                 if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
    2210           0 :                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
    2211           0 :                         get_file_infos(fileid, name_hash, &delete_pending,
    2212             :                                        &write_time_ts);
    2213             :                 }
    2214             : 
    2215           0 :                 if (delete_pending) {
    2216           0 :                         reply_nterror(req, NT_STATUS_DELETE_PENDING);
    2217           0 :                         return;
    2218             :                 }
    2219             :         }
    2220             : 
    2221           0 :         DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
    2222             :                  "total_data=%d\n", smb_fname_str_dbg(smb_fname),
    2223             :                  fsp_fnum_dbg(fsp),
    2224             :                  info_level,tran_call,total_data));
    2225             : 
    2226             :         /* Pull out any data sent here before we realloc. */
    2227           0 :         switch (info_level) {
    2228           0 :                 case SMB_INFO_QUERY_EAS_FROM_LIST:
    2229             :                 {
    2230             :                         /* Pull any EA list from the data portion. */
    2231             :                         uint32_t ea_size;
    2232             : 
    2233           0 :                         if (total_data < 4) {
    2234           0 :                                 reply_nterror(
    2235             :                                         req, NT_STATUS_INVALID_PARAMETER);
    2236           0 :                                 return;
    2237             :                         }
    2238           0 :                         ea_size = IVAL(pdata,0);
    2239             : 
    2240           0 :                         if (total_data > 0 && ea_size != total_data) {
    2241           0 :                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
    2242             : total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
    2243           0 :                                 reply_nterror(
    2244             :                                         req, NT_STATUS_INVALID_PARAMETER);
    2245           0 :                                 return;
    2246             :                         }
    2247             : 
    2248           0 :                         if (!lp_ea_support(SNUM(conn))) {
    2249           0 :                                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
    2250           0 :                                 return;
    2251             :                         }
    2252             : 
    2253             :                         /* Pull out the list of names. */
    2254           0 :                         ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
    2255           0 :                         if (!ea_list) {
    2256           0 :                                 reply_nterror(
    2257             :                                         req, NT_STATUS_INVALID_PARAMETER);
    2258           0 :                                 return;
    2259             :                         }
    2260           0 :                         break;
    2261             :                 }
    2262             : 
    2263           0 :                 case SMB_QUERY_POSIX_LOCK:
    2264             :                 {
    2265           0 :                         if (fsp == NULL ||
    2266           0 :                             fsp->fsp_flags.is_pathref ||
    2267           0 :                             fsp_get_io_fd(fsp) == -1)
    2268             :                         {
    2269           0 :                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    2270           0 :                                 return;
    2271             :                         }
    2272             : 
    2273           0 :                         if (total_data != POSIX_LOCK_DATA_SIZE) {
    2274           0 :                                 reply_nterror(
    2275             :                                         req, NT_STATUS_INVALID_PARAMETER);
    2276           0 :                                 return;
    2277             :                         }
    2278             : 
    2279             :                         /* Copy the lock range data. */
    2280           0 :                         lock_data = (char *)talloc_memdup(
    2281             :                                 req, pdata, total_data);
    2282           0 :                         if (!lock_data) {
    2283           0 :                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2284           0 :                                 return;
    2285             :                         }
    2286           0 :                         lock_data_count = total_data;
    2287           0 :                         break;
    2288             :                 }
    2289           0 :                 default:
    2290           0 :                         break;
    2291             :         }
    2292             : 
    2293           0 :         *pparams = (char *)SMB_REALLOC(*pparams,2);
    2294           0 :         if (*pparams == NULL) {
    2295           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2296           0 :                 return;
    2297             :         }
    2298           0 :         params = *pparams;
    2299           0 :         SSVAL(params,0,0);
    2300             : 
    2301             :         /*
    2302             :          * draft-leach-cifs-v1-spec-02.txt
    2303             :          * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
    2304             :          * says:
    2305             :          *
    2306             :          *  The requested information is placed in the Data portion of the
    2307             :          *  transaction response. For the information levels greater than 0x100,
    2308             :          *  the transaction response has 1 parameter word which should be
    2309             :          *  ignored by the client.
    2310             :          *
    2311             :          * However Windows only follows this rule for the IS_NAME_VALID call.
    2312             :          */
    2313           0 :         switch (info_level) {
    2314           0 :         case SMB_INFO_IS_NAME_VALID:
    2315           0 :                 param_size = 0;
    2316           0 :                 break;
    2317             :         }
    2318             : 
    2319           0 :         if ((info_level & SMB2_INFO_SPECIAL) == SMB2_INFO_SPECIAL) {
    2320             :                 /*
    2321             :                  * We use levels that start with 0xFF00
    2322             :                  * internally to represent SMB2 specific levels
    2323             :                  */
    2324           0 :                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2325           0 :                 return;
    2326             :         }
    2327             : 
    2328           0 :         status = smbd_do_qfilepathinfo(conn, req, req, info_level,
    2329             :                                        fsp, smb_fname,
    2330             :                                        delete_pending, write_time_ts,
    2331             :                                        ea_list,
    2332             :                                        lock_data_count, lock_data,
    2333           0 :                                        req->flags2, max_data_bytes,
    2334             :                                        &fixed_portion,
    2335             :                                        ppdata, &data_size);
    2336           0 :         if (!NT_STATUS_IS_OK(status)) {
    2337           0 :                 if (open_was_deferred(req->xconn, req->mid)) {
    2338             :                         /* We have re-scheduled this call. */
    2339           0 :                         return;
    2340             :                 }
    2341           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    2342           0 :                         bool ok = defer_smb1_sharing_violation(req);
    2343           0 :                         if (ok) {
    2344           0 :                                 return;
    2345             :                         }
    2346             :                 }
    2347           0 :                 reply_nterror(req, status);
    2348           0 :                 return;
    2349             :         }
    2350           0 :         if (fixed_portion > max_data_bytes) {
    2351           0 :                 reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
    2352           0 :                 return;
    2353             :         }
    2354             : 
    2355           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
    2356             :                             max_data_bytes);
    2357             : 
    2358           0 :         return;
    2359             : }
    2360             : 
    2361             : /****************************************************************************
    2362             :  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
    2363             : ****************************************************************************/
    2364             : 
    2365           0 : static void call_trans2setfilepathinfo(connection_struct *conn,
    2366             :                                        struct smb_request *req,
    2367             :                                        unsigned int tran_call,
    2368             :                                        char **pparams, int total_params,
    2369             :                                        char **ppdata, int total_data,
    2370             :                                        unsigned int max_data_bytes)
    2371             : {
    2372           0 :         char *params = *pparams;
    2373           0 :         char *pdata = *ppdata;
    2374             :         uint16_t info_level;
    2375           0 :         struct smb_filename *smb_fname = NULL;
    2376           0 :         struct files_struct *dirfsp = NULL;
    2377           0 :         files_struct *fsp = NULL;
    2378           0 :         NTSTATUS status = NT_STATUS_OK;
    2379           0 :         int data_return_size = 0;
    2380             :         int ret;
    2381             : 
    2382           0 :         if (!params) {
    2383           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2384           0 :                 return;
    2385             :         }
    2386             : 
    2387           0 :         if (tran_call == TRANSACT2_SETFILEINFO) {
    2388           0 :                 if (total_params < 4) {
    2389           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2390           0 :                         return;
    2391             :                 }
    2392             : 
    2393           0 :                 fsp = file_fsp(req, SVAL(params,0));
    2394             :                 /* Basic check for non-null fsp. */
    2395           0 :                 if (!check_fsp_open(conn, req, fsp)) {
    2396           0 :                         return;
    2397             :                 }
    2398           0 :                 info_level = SVAL(params,2);
    2399             : 
    2400           0 :                 if (INFO_LEVEL_IS_UNIX(info_level)) {
    2401           0 :                         if (!lp_smb1_unix_extensions()) {
    2402           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2403           0 :                                 return;
    2404             :                         }
    2405           0 :                         if (!req->posix_pathnames) {
    2406           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2407           0 :                                 return;
    2408             :                         }
    2409             :                 }
    2410             : 
    2411           0 :                 smb_fname = fsp->fsp_name;
    2412             : 
    2413           0 :                 if (fsp_get_pathref_fd(fsp) == -1) {
    2414             :                         /*
    2415             :                          * This is actually a SETFILEINFO on a directory
    2416             :                          * handle (returned from an NT SMB). NT5.0 seems
    2417             :                          * to do this call. JRA.
    2418             :                          */
    2419           0 :                         ret = vfs_stat(conn, smb_fname);
    2420           0 :                         if (ret != 0) {
    2421           0 :                                 DBG_NOTICE("vfs_stat of %s failed (%s)\n",
    2422             :                                         smb_fname_str_dbg(smb_fname),
    2423             :                                         strerror(errno));
    2424           0 :                                 reply_nterror(req,
    2425             :                                         map_nt_error_from_unix(errno));
    2426           0 :                                 return;
    2427             :                         }
    2428           0 :                 } else if (fsp->print_file) {
    2429             :                         /*
    2430             :                          * Doing a DELETE_ON_CLOSE should cancel a print job.
    2431             :                          */
    2432           0 :                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
    2433             : 
    2434           0 :                                 fsp->fsp_flags.delete_on_close = true;
    2435             : 
    2436           0 :                                 DEBUG(3,("call_trans2setfilepathinfo: "
    2437             :                                          "Cancelling print job (%s)\n",
    2438             :                                          fsp_str_dbg(fsp)));
    2439             : 
    2440           0 :                                 SSVAL(params,0,0);
    2441           0 :                                 send_trans2_replies(conn, req, NT_STATUS_OK, params, 2,
    2442             :                                                     *ppdata, 0,
    2443             :                                                     max_data_bytes);
    2444           0 :                                 return;
    2445             :                         } else {
    2446           0 :                                 reply_nterror(req,
    2447             :                                         NT_STATUS_OBJECT_PATH_NOT_FOUND);
    2448           0 :                                 return;
    2449             :                         }
    2450             :                 } else {
    2451             :                         /*
    2452             :                          * Original code - this is an open file.
    2453             :                          */
    2454           0 :                         status = vfs_stat_fsp(fsp);
    2455           0 :                         if (!NT_STATUS_IS_OK(status)) {
    2456           0 :                                 DEBUG(3,("call_trans2setfilepathinfo: fstat "
    2457             :                                          "of %s failed (%s)\n", fsp_fnum_dbg(fsp),
    2458             :                                          nt_errstr(status)));
    2459           0 :                                 reply_nterror(req, status);
    2460           0 :                                 return;
    2461             :                         }
    2462             :                 }
    2463             :         } else {
    2464           0 :                 char *fname = NULL;
    2465           0 :                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
    2466           0 :                 bool require_existing_object = true;
    2467           0 :                 NTTIME twrp = 0;
    2468             : 
    2469             :                 /* set path info */
    2470           0 :                 if (total_params < 7) {
    2471           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2472           0 :                         return;
    2473             :                 }
    2474             : 
    2475           0 :                 info_level = SVAL(params,0);
    2476             : 
    2477           0 :                 if (INFO_LEVEL_IS_UNIX(info_level)) {
    2478           0 :                         if (!lp_smb1_unix_extensions()) {
    2479           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2480           0 :                                 return;
    2481             :                         }
    2482           0 :                         if (!req->posix_pathnames) {
    2483           0 :                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2484           0 :                                 return;
    2485             :                         }
    2486             :                 }
    2487             : 
    2488           0 :                 if (req->posix_pathnames) {
    2489           0 :                         srvstr_get_path_posix(req,
    2490             :                                 params,
    2491           0 :                                 req->flags2,
    2492             :                                 &fname,
    2493           0 :                                 &params[6],
    2494           0 :                                 total_params - 6,
    2495             :                                 STR_TERMINATE,
    2496             :                                 &status);
    2497             :                 } else {
    2498           0 :                         srvstr_get_path(req,
    2499             :                                 params,
    2500           0 :                                 req->flags2,
    2501             :                                 &fname,
    2502           0 :                                 &params[6],
    2503           0 :                                 total_params - 6,
    2504             :                                 STR_TERMINATE,
    2505             :                                 &status);
    2506             :                 }
    2507           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2508           0 :                         reply_nterror(req, status);
    2509           0 :                         return;
    2510             :                 }
    2511             : 
    2512           0 :                 if (ucf_flags & UCF_GMT_PATHNAME) {
    2513           0 :                         extract_snapshot_token(fname, &twrp);
    2514             :                 }
    2515           0 :                 status = filename_convert_dirfsp(req,
    2516             :                                                  conn,
    2517             :                                                  fname,
    2518             :                                                  ucf_flags,
    2519             :                                                  twrp,
    2520             :                                                  &dirfsp,
    2521             :                                                  &smb_fname);
    2522           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2523           0 :                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
    2524           0 :                                 reply_botherror(req,
    2525             :                                                 NT_STATUS_PATH_NOT_COVERED,
    2526             :                                                 ERRSRV, ERRbadpath);
    2527           0 :                                 return;
    2528             :                         }
    2529           0 :                         reply_nterror(req, status);
    2530           0 :                         return;
    2531             :                 }
    2532             : 
    2533             :                 /*
    2534             :                  * smb_fname->fsp may be NULL if smb_fname points at a symlink
    2535             :                  * and we're in POSIX context, so be careful when using fsp
    2536             :                  * below, it can still be NULL.
    2537             :                  */
    2538           0 :                 fsp = smb_fname->fsp;
    2539             : 
    2540             :                 /*
    2541             :                  * There are 4 info levels which can
    2542             :                  * create a new object in the filesystem.
    2543             :                  * They are:
    2544             :                  * SMB_SET_FILE_UNIX_LINK -> creates POSIX symlink.
    2545             :                  * SMB_POSIX_PATH_OPEN -> creates POSIX file or directory.
    2546             :                  * SMB_SET_FILE_UNIX_BASIC:
    2547             :                  * SMB_SET_FILE_UNIX_INFO2: can create a POSIX special file.
    2548             :                  *
    2549             :                  * These info levels do not require an existing object.
    2550             :                  */
    2551           0 :                 switch (info_level) {
    2552           0 :                 case SMB_SET_FILE_UNIX_LINK:
    2553             :                 case SMB_POSIX_PATH_OPEN:
    2554             :                 case SMB_SET_FILE_UNIX_BASIC:
    2555             :                 case SMB_SET_FILE_UNIX_INFO2:
    2556           0 :                         require_existing_object = false;
    2557           0 :                         break;
    2558           0 :                 default:
    2559           0 :                         break;
    2560             :                 }
    2561             : 
    2562           0 :                 if (!VALID_STAT(smb_fname->st) && require_existing_object) {
    2563           0 :                         reply_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    2564             :                 }
    2565             :         }
    2566             : 
    2567           0 :         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
    2568             :                  "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
    2569             :                  fsp_fnum_dbg(fsp),
    2570             :                  info_level,total_data));
    2571             : 
    2572             :         /* Realloc the parameter size */
    2573           0 :         *pparams = (char *)SMB_REALLOC(*pparams,2);
    2574           0 :         if (*pparams == NULL) {
    2575           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2576           0 :                 return;
    2577             :         }
    2578           0 :         params = *pparams;
    2579             : 
    2580           0 :         SSVAL(params,0,0);
    2581             : 
    2582           0 :         status = smbd_do_setfilepathinfo(conn, req, req,
    2583             :                                          info_level,
    2584             :                                          fsp,
    2585             :                                          smb_fname,
    2586             :                                          ppdata, total_data,
    2587             :                                          &data_return_size);
    2588           0 :         if (!NT_STATUS_IS_OK(status)) {
    2589           0 :                 if (open_was_deferred(req->xconn, req->mid)) {
    2590             :                         /* We have re-scheduled this call. */
    2591           0 :                         return;
    2592             :                 }
    2593           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    2594           0 :                         bool ok = defer_smb1_sharing_violation(req);
    2595           0 :                         if (ok) {
    2596           0 :                                 return;
    2597             :                         }
    2598             :                 }
    2599           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_EVENT_PENDING)) {
    2600             :                         /* We have re-scheduled this call. */
    2601           0 :                         return;
    2602             :                 }
    2603           0 :                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
    2604           0 :                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
    2605             :                                         ERRSRV, ERRbadpath);
    2606           0 :                         return;
    2607             :                 }
    2608           0 :                 if (info_level == SMB_POSIX_PATH_OPEN) {
    2609           0 :                         reply_openerror(req, status);
    2610           0 :                         return;
    2611             :                 }
    2612             : 
    2613             :                 /*
    2614             :                  * Invalid EA name needs to return 2 param bytes,
    2615             :                  * not a zero-length error packet.
    2616             :                  */
    2617           0 :                 if (NT_STATUS_EQUAL(status, STATUS_INVALID_EA_NAME)) {
    2618           0 :                         send_trans2_replies(conn, req, status, params, 2, NULL, 0,
    2619             :                                         max_data_bytes);
    2620             :                 } else {
    2621           0 :                         reply_nterror(req, status);
    2622             :                 }
    2623           0 :                 return;
    2624             :         }
    2625             : 
    2626           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, data_return_size,
    2627             :                             max_data_bytes);
    2628             : 
    2629           0 :         return;
    2630             : }
    2631             : 
    2632             : /****************************************************************************
    2633             :  Reply to a TRANS2_MKDIR (make directory with extended attributes).
    2634             : ****************************************************************************/
    2635             : 
    2636           0 : static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
    2637             :                              char **pparams, int total_params,
    2638             :                              char **ppdata, int total_data,
    2639             :                              unsigned int max_data_bytes)
    2640             : {
    2641           0 :         struct files_struct *dirfsp = NULL;
    2642           0 :         struct files_struct *fsp = NULL;
    2643           0 :         struct smb_filename *smb_dname = NULL;
    2644           0 :         char *params = *pparams;
    2645           0 :         char *pdata = *ppdata;
    2646           0 :         char *directory = NULL;
    2647           0 :         NTSTATUS status = NT_STATUS_OK;
    2648           0 :         struct ea_list *ea_list = NULL;
    2649           0 :         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
    2650           0 :         NTTIME twrp = 0;
    2651           0 :         TALLOC_CTX *ctx = talloc_tos();
    2652             : 
    2653           0 :         if (!CAN_WRITE(conn)) {
    2654           0 :                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    2655           0 :                 return;
    2656             :         }
    2657             : 
    2658           0 :         if (total_params < 5) {
    2659           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2660           0 :                 return;
    2661             :         }
    2662             : 
    2663           0 :         if (req->posix_pathnames) {
    2664           0 :                 srvstr_get_path_posix(ctx,
    2665             :                         params,
    2666           0 :                         req->flags2,
    2667             :                         &directory,
    2668           0 :                         &params[4],
    2669           0 :                         total_params - 4,
    2670             :                         STR_TERMINATE,
    2671             :                         &status);
    2672             :         } else {
    2673           0 :                 srvstr_get_path(ctx,
    2674             :                         params,
    2675           0 :                         req->flags2,
    2676             :                         &directory,
    2677           0 :                         &params[4],
    2678           0 :                         total_params - 4,
    2679             :                         STR_TERMINATE,
    2680             :                         &status);
    2681             :         }
    2682           0 :         if (!NT_STATUS_IS_OK(status)) {
    2683           0 :                 reply_nterror(req, status);
    2684           0 :                 return;
    2685             :         }
    2686             : 
    2687           0 :         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
    2688             : 
    2689           0 :         if (ucf_flags & UCF_GMT_PATHNAME) {
    2690           0 :                 extract_snapshot_token(directory, &twrp);
    2691             :         }
    2692           0 :         status = filename_convert_dirfsp(ctx,
    2693             :                                          conn,
    2694             :                                          directory,
    2695             :                                          ucf_flags,
    2696             :                                          twrp,
    2697             :                                          &dirfsp,
    2698             :                                          &smb_dname);
    2699           0 :         if (!NT_STATUS_IS_OK(status)) {
    2700           0 :                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
    2701           0 :                         reply_botherror(req,
    2702             :                                 NT_STATUS_PATH_NOT_COVERED,
    2703             :                                 ERRSRV, ERRbadpath);
    2704           0 :                         return;
    2705             :                 }
    2706           0 :                 reply_nterror(req, status);
    2707           0 :                 return;
    2708             :         }
    2709             : 
    2710             :         /*
    2711             :          * OS/2 workplace shell seems to send SET_EA requests of "null"
    2712             :          * length (4 bytes containing IVAL 4).
    2713             :          * They seem to have no effect. Bug #3212. JRA.
    2714             :          */
    2715             : 
    2716           0 :         if (total_data && (total_data != 4)) {
    2717             :                 /* Any data in this call is an EA list. */
    2718           0 :                 if (total_data < 10) {
    2719           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2720           0 :                         goto out;
    2721             :                 }
    2722             : 
    2723           0 :                 if (IVAL(pdata,0) > total_data) {
    2724           0 :                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
    2725             :                                 IVAL(pdata,0), (unsigned int)total_data));
    2726           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2727           0 :                         goto out;
    2728             :                 }
    2729             : 
    2730           0 :                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
    2731           0 :                                        total_data - 4);
    2732           0 :                 if (!ea_list) {
    2733           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2734           0 :                         goto out;
    2735             :                 }
    2736             : 
    2737           0 :                 if (!lp_ea_support(SNUM(conn))) {
    2738           0 :                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
    2739           0 :                         goto out;
    2740             :                 }
    2741             :         }
    2742             :         /* If total_data == 4 Windows doesn't care what values
    2743             :          * are placed in that field, it just ignores them.
    2744             :          * The System i QNTC IBM SMB client puts bad values here,
    2745             :          * so ignore them. */
    2746             : 
    2747           0 :         status = SMB_VFS_CREATE_FILE(
    2748             :                 conn,                                   /* conn */
    2749             :                 req,                                    /* req */
    2750             :                 dirfsp,                                 /* dirfsp */
    2751             :                 smb_dname,                              /* fname */
    2752             :                 MAXIMUM_ALLOWED_ACCESS,                 /* access_mask */
    2753             :                 FILE_SHARE_NONE,                        /* share_access */
    2754             :                 FILE_CREATE,                            /* create_disposition*/
    2755             :                 FILE_DIRECTORY_FILE,                    /* create_options */
    2756             :                 FILE_ATTRIBUTE_DIRECTORY,               /* file_attributes */
    2757             :                 0,                                      /* oplock_request */
    2758             :                 NULL,                                   /* lease */
    2759             :                 0,                                      /* allocation_size */
    2760             :                 0,                                      /* private_flags */
    2761             :                 NULL,                                   /* sd */
    2762             :                 NULL,                                   /* ea_list */
    2763             :                 &fsp,                                       /* result */
    2764             :                 NULL,                                   /* pinfo */
    2765             :                 NULL, NULL);                            /* create context */
    2766           0 :         if (!NT_STATUS_IS_OK(status)) {
    2767           0 :                 reply_nterror(req, status);
    2768           0 :                 goto out;
    2769             :         }
    2770             : 
    2771             :         /* Try and set any given EA. */
    2772           0 :         if (ea_list) {
    2773           0 :                 status = set_ea(conn, fsp, ea_list);
    2774           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2775           0 :                         reply_nterror(req, status);
    2776           0 :                         goto out;
    2777             :                 }
    2778             :         }
    2779             : 
    2780             :         /* Realloc the parameter and data sizes */
    2781           0 :         *pparams = (char *)SMB_REALLOC(*pparams,2);
    2782           0 :         if(*pparams == NULL) {
    2783           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2784           0 :                 goto out;
    2785             :         }
    2786           0 :         params = *pparams;
    2787             : 
    2788           0 :         SSVAL(params,0,0);
    2789             : 
    2790           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, 0, max_data_bytes);
    2791             : 
    2792           0 :  out:
    2793           0 :         if (fsp != NULL) {
    2794           0 :                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
    2795             :         }
    2796           0 :         TALLOC_FREE(smb_dname);
    2797           0 :         return;
    2798             : }
    2799             : 
    2800             : /****************************************************************************
    2801             :  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
    2802             :  We don't actually do this - we just send a null response.
    2803             : ****************************************************************************/
    2804             : 
    2805           0 : static void call_trans2findnotifyfirst(connection_struct *conn,
    2806             :                                        struct smb_request *req,
    2807             :                                        char **pparams, int total_params,
    2808             :                                        char **ppdata, int total_data,
    2809             :                                        unsigned int max_data_bytes)
    2810             : {
    2811           0 :         char *params = *pparams;
    2812             :         uint16_t info_level;
    2813             : 
    2814           0 :         if (total_params < 6) {
    2815           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2816           0 :                 return;
    2817             :         }
    2818             : 
    2819           0 :         info_level = SVAL(params,4);
    2820           0 :         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
    2821             : 
    2822           0 :         switch (info_level) {
    2823           0 :                 case 1:
    2824             :                 case 2:
    2825           0 :                         break;
    2826           0 :                 default:
    2827           0 :                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2828           0 :                         return;
    2829             :         }
    2830             : 
    2831             :         /* Realloc the parameter and data sizes */
    2832           0 :         *pparams = (char *)SMB_REALLOC(*pparams,6);
    2833           0 :         if (*pparams == NULL) {
    2834           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2835           0 :                 return;
    2836             :         }
    2837           0 :         params = *pparams;
    2838             : 
    2839           0 :         SSVAL(params,0,fnf_handle);
    2840           0 :         SSVAL(params,2,0); /* No changes */
    2841           0 :         SSVAL(params,4,0); /* No EA errors */
    2842             : 
    2843           0 :         fnf_handle++;
    2844             : 
    2845           0 :         if(fnf_handle == 0)
    2846           0 :                 fnf_handle = 257;
    2847             : 
    2848           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, 6, *ppdata, 0, max_data_bytes);
    2849             : 
    2850           0 :         return;
    2851             : }
    2852             : 
    2853             : /****************************************************************************
    2854             :  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
    2855             :  changes). Currently this does nothing.
    2856             : ****************************************************************************/
    2857             : 
    2858           0 : static void call_trans2findnotifynext(connection_struct *conn,
    2859             :                                       struct smb_request *req,
    2860             :                                       char **pparams, int total_params,
    2861             :                                       char **ppdata, int total_data,
    2862             :                                       unsigned int max_data_bytes)
    2863             : {
    2864           0 :         char *params = *pparams;
    2865             : 
    2866           0 :         DEBUG(3,("call_trans2findnotifynext\n"));
    2867             : 
    2868             :         /* Realloc the parameter and data sizes */
    2869           0 :         *pparams = (char *)SMB_REALLOC(*pparams,4);
    2870           0 :         if (*pparams == NULL) {
    2871           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2872           0 :                 return;
    2873             :         }
    2874           0 :         params = *pparams;
    2875             : 
    2876           0 :         SSVAL(params,0,0); /* No changes */
    2877           0 :         SSVAL(params,2,0); /* No EA errors */
    2878             : 
    2879           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, params, 4, *ppdata, 0, max_data_bytes);
    2880             : 
    2881           0 :         return;
    2882             : }
    2883             : 
    2884             : /****************************************************************************
    2885             :  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
    2886             : ****************************************************************************/
    2887             : 
    2888           0 : static void call_trans2getdfsreferral(connection_struct *conn,
    2889             :                                       struct smb_request *req,
    2890             :                                       char **pparams, int total_params,
    2891             :                                       char **ppdata, int total_data,
    2892             :                                       unsigned int max_data_bytes)
    2893             : {
    2894           0 :         char *params = *pparams;
    2895           0 :         char *pathname = NULL;
    2896           0 :         int reply_size = 0;
    2897             :         int max_referral_level;
    2898           0 :         NTSTATUS status = NT_STATUS_OK;
    2899           0 :         TALLOC_CTX *ctx = talloc_tos();
    2900             : 
    2901           0 :         DEBUG(10,("call_trans2getdfsreferral\n"));
    2902             : 
    2903           0 :         if (total_params < 3) {
    2904           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2905           0 :                 return;
    2906             :         }
    2907             : 
    2908           0 :         max_referral_level = SVAL(params,0);
    2909             : 
    2910           0 :         if(!lp_host_msdfs()) {
    2911           0 :                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
    2912           0 :                 return;
    2913             :         }
    2914             : 
    2915           0 :         srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
    2916             :                     total_params - 2, STR_TERMINATE);
    2917           0 :         if (!pathname) {
    2918           0 :                 reply_nterror(req, NT_STATUS_NOT_FOUND);
    2919           0 :                 return;
    2920             :         }
    2921           0 :         if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
    2922             :                                             ppdata,&status)) < 0) {
    2923           0 :                 reply_nterror(req, status);
    2924           0 :                 return;
    2925             :         }
    2926             : 
    2927           0 :         SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
    2928             :               SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
    2929           0 :         send_trans2_replies(conn, req, NT_STATUS_OK, 0,0,*ppdata,reply_size, max_data_bytes);
    2930             : 
    2931           0 :         return;
    2932             : }
    2933             : 
    2934             : #define LMCAT_SPL       0x53
    2935             : #define LMFUNC_GETJOBID 0x60
    2936             : 
    2937             : /****************************************************************************
    2938             :  Reply to a TRANS2_IOCTL - used for OS/2 printing.
    2939             : ****************************************************************************/
    2940             : 
    2941           0 : static void call_trans2ioctl(connection_struct *conn,
    2942             :                              struct smb_request *req,
    2943             :                              char **pparams, int total_params,
    2944             :                              char **ppdata, int total_data,
    2945             :                              unsigned int max_data_bytes)
    2946             : {
    2947           0 :         const struct loadparm_substitution *lp_sub =
    2948           0 :                 loadparm_s3_global_substitution();
    2949           0 :         char *pdata = *ppdata;
    2950           0 :         files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
    2951             :         NTSTATUS status;
    2952           0 :         size_t len = 0;
    2953             : 
    2954             :         /* check for an invalid fid before proceeding */
    2955             : 
    2956           0 :         if (!fsp) {
    2957           0 :                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    2958           0 :                 return;
    2959             :         }
    2960             : 
    2961           0 :         if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
    2962           0 :             && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
    2963           0 :                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
    2964           0 :                 if (*ppdata == NULL) {
    2965           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    2966           0 :                         return;
    2967             :                 }
    2968           0 :                 pdata = *ppdata;
    2969             : 
    2970             :                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
    2971             :                         CAN ACCEPT THIS IN UNICODE. JRA. */
    2972             : 
    2973             :                 /* Job number */
    2974           0 :                 SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
    2975             : 
    2976           0 :                 status = srvstr_push(pdata, req->flags2, pdata + 2,
    2977             :                             lp_netbios_name(), 15,
    2978             :                             STR_ASCII|STR_TERMINATE, &len); /* Our NetBIOS name */
    2979           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2980           0 :                         reply_nterror(req, status);
    2981           0 :                         return;
    2982             :                 }
    2983           0 :                 status = srvstr_push(pdata, req->flags2, pdata+18,
    2984             :                             lp_servicename(talloc_tos(), lp_sub, SNUM(conn)), 13,
    2985             :                             STR_ASCII|STR_TERMINATE, &len); /* Service name */
    2986           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2987           0 :                         reply_nterror(req, status);
    2988           0 :                         return;
    2989             :                 }
    2990           0 :                 send_trans2_replies(conn, req, NT_STATUS_OK, *pparams, 0, *ppdata, 32,
    2991             :                                     max_data_bytes);
    2992           0 :                 return;
    2993             :         }
    2994             : 
    2995           0 :         DEBUG(2,("Unknown TRANS2_IOCTL\n"));
    2996           0 :         reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
    2997             : }
    2998             : 
    2999           8 : static void handle_trans2(connection_struct *conn, struct smb_request *req,
    3000             :                           struct trans_state *state)
    3001             : {
    3002           8 :         if (get_Protocol() >= PROTOCOL_NT1) {
    3003           8 :                 req->flags2 |= 0x40; /* IS_LONG_NAME */
    3004           8 :                 SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
    3005             :         }
    3006             : 
    3007           8 :         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
    3008           0 :                 if (state->call != TRANSACT2_QFSINFO &&
    3009           0 :                     state->call != TRANSACT2_SETFSINFO) {
    3010           0 :                         DEBUG(0,("handle_trans2: encryption required "
    3011             :                                 "with call 0x%x\n",
    3012             :                                 (unsigned int)state->call));
    3013           0 :                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    3014           0 :                         return;
    3015             :                 }
    3016             :         }
    3017             : 
    3018           8 :         SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
    3019             : 
    3020             :         /* Now we must call the relevant TRANS2 function */
    3021           8 :         switch(state->call)  {
    3022           0 :         case TRANSACT2_OPEN:
    3023             :         {
    3024           0 :                 START_PROFILE(Trans2_open);
    3025           0 :                 call_trans2open(conn, req,
    3026           0 :                                 &state->param, state->total_param,
    3027           0 :                                 &state->data, state->total_data,
    3028             :                                 state->max_data_return);
    3029           0 :                 END_PROFILE(Trans2_open);
    3030           0 :                 break;
    3031             :         }
    3032             : 
    3033           0 :         case TRANSACT2_FINDFIRST:
    3034             :         {
    3035           0 :                 START_PROFILE(Trans2_findfirst);
    3036           0 :                 call_trans2findfirst(conn, req,
    3037           0 :                                      &state->param, state->total_param,
    3038           0 :                                      &state->data, state->total_data,
    3039             :                                      state->max_data_return);
    3040           0 :                 END_PROFILE(Trans2_findfirst);
    3041           0 :                 break;
    3042             :         }
    3043             : 
    3044           0 :         case TRANSACT2_FINDNEXT:
    3045             :         {
    3046           0 :                 START_PROFILE(Trans2_findnext);
    3047           0 :                 call_trans2findnext(conn, req,
    3048           0 :                                     &state->param, state->total_param,
    3049           0 :                                     &state->data, state->total_data,
    3050             :                                     state->max_data_return);
    3051           0 :                 END_PROFILE(Trans2_findnext);
    3052           0 :                 break;
    3053             :         }
    3054             : 
    3055           8 :         case TRANSACT2_QFSINFO:
    3056             :         {
    3057           8 :                 START_PROFILE(Trans2_qfsinfo);
    3058          16 :                 call_trans2qfsinfo(conn, req,
    3059           8 :                                    &state->param, state->total_param,
    3060           8 :                                    &state->data, state->total_data,
    3061             :                                    state->max_data_return);
    3062           8 :                 END_PROFILE(Trans2_qfsinfo);
    3063           8 :             break;
    3064             :         }
    3065             : 
    3066           0 :         case TRANSACT2_SETFSINFO:
    3067             :         {
    3068           0 :                 START_PROFILE(Trans2_setfsinfo);
    3069           0 :                 call_trans2setfsinfo(conn, req,
    3070           0 :                                      &state->param, state->total_param,
    3071           0 :                                      &state->data, state->total_data,
    3072             :                                      state->max_data_return);
    3073           0 :                 END_PROFILE(Trans2_setfsinfo);
    3074           0 :                 break;
    3075             :         }
    3076             : 
    3077           0 :         case TRANSACT2_QPATHINFO:
    3078             :         case TRANSACT2_QFILEINFO:
    3079             :         {
    3080           0 :                 START_PROFILE(Trans2_qpathinfo);
    3081           0 :                 call_trans2qfilepathinfo(conn, req, state->call,
    3082           0 :                                          &state->param, state->total_param,
    3083           0 :                                          &state->data, state->total_data,
    3084             :                                          state->max_data_return);
    3085           0 :                 END_PROFILE(Trans2_qpathinfo);
    3086           0 :                 break;
    3087             :         }
    3088             : 
    3089           0 :         case TRANSACT2_SETPATHINFO:
    3090             :         case TRANSACT2_SETFILEINFO:
    3091             :         {
    3092           0 :                 START_PROFILE(Trans2_setpathinfo);
    3093           0 :                 call_trans2setfilepathinfo(conn, req, state->call,
    3094           0 :                                            &state->param, state->total_param,
    3095           0 :                                            &state->data, state->total_data,
    3096             :                                            state->max_data_return);
    3097           0 :                 END_PROFILE(Trans2_setpathinfo);
    3098           0 :                 break;
    3099             :         }
    3100             : 
    3101           0 :         case TRANSACT2_FINDNOTIFYFIRST:
    3102             :         {
    3103           0 :                 START_PROFILE(Trans2_findnotifyfirst);
    3104           0 :                 call_trans2findnotifyfirst(conn, req,
    3105           0 :                                            &state->param, state->total_param,
    3106           0 :                                            &state->data, state->total_data,
    3107             :                                            state->max_data_return);
    3108           0 :                 END_PROFILE(Trans2_findnotifyfirst);
    3109           0 :                 break;
    3110             :         }
    3111             : 
    3112           0 :         case TRANSACT2_FINDNOTIFYNEXT:
    3113             :         {
    3114           0 :                 START_PROFILE(Trans2_findnotifynext);
    3115           0 :                 call_trans2findnotifynext(conn, req,
    3116           0 :                                           &state->param, state->total_param,
    3117           0 :                                           &state->data, state->total_data,
    3118             :                                           state->max_data_return);
    3119           0 :                 END_PROFILE(Trans2_findnotifynext);
    3120           0 :                 break;
    3121             :         }
    3122             : 
    3123           0 :         case TRANSACT2_MKDIR:
    3124             :         {
    3125           0 :                 START_PROFILE(Trans2_mkdir);
    3126           0 :                 call_trans2mkdir(conn, req,
    3127           0 :                                  &state->param, state->total_param,
    3128           0 :                                  &state->data, state->total_data,
    3129             :                                  state->max_data_return);
    3130           0 :                 END_PROFILE(Trans2_mkdir);
    3131           0 :                 break;
    3132             :         }
    3133             : 
    3134           0 :         case TRANSACT2_GET_DFS_REFERRAL:
    3135             :         {
    3136           0 :                 START_PROFILE(Trans2_get_dfs_referral);
    3137           0 :                 call_trans2getdfsreferral(conn, req,
    3138           0 :                                           &state->param, state->total_param,
    3139           0 :                                           &state->data, state->total_data,
    3140             :                                           state->max_data_return);
    3141           0 :                 END_PROFILE(Trans2_get_dfs_referral);
    3142           0 :                 break;
    3143             :         }
    3144             : 
    3145           0 :         case TRANSACT2_IOCTL:
    3146             :         {
    3147           0 :                 START_PROFILE(Trans2_ioctl);
    3148           0 :                 call_trans2ioctl(conn, req,
    3149           0 :                                  &state->param, state->total_param,
    3150           0 :                                  &state->data, state->total_data,
    3151             :                                  state->max_data_return);
    3152           0 :                 END_PROFILE(Trans2_ioctl);
    3153           0 :                 break;
    3154             :         }
    3155             : 
    3156           0 :         default:
    3157             :                 /* Error in request */
    3158           0 :                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
    3159           0 :                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
    3160             :         }
    3161             : }
    3162             : 
    3163             : /****************************************************************************
    3164             :  Reply to a SMBtrans2.
    3165             :  ****************************************************************************/
    3166             : 
    3167           8 : void reply_trans2(struct smb_request *req)
    3168             : {
    3169           8 :         connection_struct *conn = req->conn;
    3170             :         unsigned int dsoff;
    3171             :         unsigned int dscnt;
    3172             :         unsigned int psoff;
    3173             :         unsigned int pscnt;
    3174             :         unsigned int tran_call;
    3175             :         struct trans_state *state;
    3176             :         NTSTATUS result;
    3177             : 
    3178           8 :         START_PROFILE(SMBtrans2);
    3179             : 
    3180           8 :         if (req->wct < 14) {
    3181           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    3182           0 :                 END_PROFILE(SMBtrans2);
    3183           4 :                 return;
    3184             :         }
    3185             : 
    3186           8 :         dsoff = SVAL(req->vwv+12, 0);
    3187           8 :         dscnt = SVAL(req->vwv+11, 0);
    3188           8 :         psoff = SVAL(req->vwv+10, 0);
    3189           8 :         pscnt = SVAL(req->vwv+9, 0);
    3190           8 :         tran_call = SVAL(req->vwv+14, 0);
    3191             : 
    3192           8 :         result = allow_new_trans(conn->pending_trans, req->mid);
    3193           8 :         if (!NT_STATUS_IS_OK(result)) {
    3194           0 :                 DEBUG(2, ("Got invalid trans2 request: %s\n",
    3195             :                           nt_errstr(result)));
    3196           0 :                 reply_nterror(req, result);
    3197           0 :                 END_PROFILE(SMBtrans2);
    3198           0 :                 return;
    3199             :         }
    3200             : 
    3201           8 :         if (IS_IPC(conn)) {
    3202           0 :                 switch (tran_call) {
    3203             :                 /* List the allowed trans2 calls on IPC$ */
    3204           0 :                 case TRANSACT2_OPEN:
    3205             :                 case TRANSACT2_GET_DFS_REFERRAL:
    3206             :                 case TRANSACT2_QFILEINFO:
    3207             :                 case TRANSACT2_QFSINFO:
    3208             :                 case TRANSACT2_SETFSINFO:
    3209           0 :                         break;
    3210           0 :                 default:
    3211           0 :                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    3212           0 :                         END_PROFILE(SMBtrans2);
    3213           0 :                         return;
    3214             :                 }
    3215           4 :         }
    3216             : 
    3217           8 :         if ((state = talloc(conn, struct trans_state)) == NULL) {
    3218           0 :                 DEBUG(0, ("talloc failed\n"));
    3219           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    3220           0 :                 END_PROFILE(SMBtrans2);
    3221           0 :                 return;
    3222             :         }
    3223             : 
    3224           8 :         state->cmd = SMBtrans2;
    3225             : 
    3226           8 :         state->mid = req->mid;
    3227           8 :         state->vuid = req->vuid;
    3228           8 :         state->setup_count = SVAL(req->vwv+13, 0);
    3229           8 :         state->setup = NULL;
    3230           8 :         state->total_param = SVAL(req->vwv+0, 0);
    3231           8 :         state->param = NULL;
    3232           8 :         state->total_data =  SVAL(req->vwv+1, 0);
    3233           8 :         state->data = NULL;
    3234           8 :         state->max_param_return = SVAL(req->vwv+2, 0);
    3235           8 :         state->max_data_return  = SVAL(req->vwv+3, 0);
    3236           8 :         state->max_setup_return = SVAL(req->vwv+4, 0);
    3237           8 :         state->close_on_completion = BITSETW(req->vwv+5, 0);
    3238           8 :         state->one_way = BITSETW(req->vwv+5, 1);
    3239             : 
    3240           8 :         state->call = tran_call;
    3241             : 
    3242             :         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
    3243             :            is so as a sanity check */
    3244           8 :         if (state->setup_count != 1) {
    3245             :                 /*
    3246             :                  * Need to have rc=0 for ioctl to get job id for OS/2.
    3247             :                  *  Network printing will fail if function is not successful.
    3248             :                  *  Similar function in reply.c will be used if protocol
    3249             :                  *  is LANMAN1.0 instead of LM1.2X002.
    3250             :                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
    3251             :                  *  outbuf doesn't have to be set(only job id is used).
    3252             :                  */
    3253           0 :                 if ( (state->setup_count == 4)
    3254           0 :                      && (tran_call == TRANSACT2_IOCTL)
    3255           0 :                      && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
    3256           0 :                      && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
    3257           0 :                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
    3258             :                 } else {
    3259           0 :                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
    3260           0 :                         DEBUG(2,("Transaction is %d\n",tran_call));
    3261           0 :                         TALLOC_FREE(state);
    3262           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    3263           0 :                         END_PROFILE(SMBtrans2);
    3264           0 :                         return;
    3265             :                 }
    3266             :         }
    3267             : 
    3268           8 :         if ((dscnt > state->total_data) || (pscnt > state->total_param))
    3269           0 :                 goto bad_param;
    3270             : 
    3271           8 :         if (state->total_data) {
    3272             : 
    3273           0 :                 if (smb_buffer_oob(state->total_data, 0, dscnt)
    3274           0 :                     || smb_buffer_oob(smb_len(req->inbuf), dsoff, dscnt)) {
    3275           0 :                         goto bad_param;
    3276             :                 }
    3277             : 
    3278             :                 /* Can't use talloc here, the core routines do realloc on the
    3279             :                  * params and data. */
    3280           0 :                 state->data = (char *)SMB_MALLOC(state->total_data);
    3281           0 :                 if (state->data == NULL) {
    3282           0 :                         DEBUG(0,("reply_trans2: data malloc fail for %u "
    3283             :                                  "bytes !\n", (unsigned int)state->total_data));
    3284           0 :                         TALLOC_FREE(state);
    3285           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    3286           0 :                         END_PROFILE(SMBtrans2);
    3287           0 :                         return;
    3288             :                 }
    3289             : 
    3290           0 :                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
    3291             :         }
    3292             : 
    3293           8 :         if (state->total_param) {
    3294             : 
    3295           8 :                 if (smb_buffer_oob(state->total_param, 0, pscnt)
    3296           8 :                     || smb_buffer_oob(smb_len(req->inbuf), psoff, pscnt)) {
    3297           0 :                         goto bad_param;
    3298             :                 }
    3299             : 
    3300             :                 /* Can't use talloc here, the core routines do realloc on the
    3301             :                  * params and data. */
    3302           8 :                 state->param = (char *)SMB_MALLOC(state->total_param);
    3303           8 :                 if (state->param == NULL) {
    3304           0 :                         DEBUG(0,("reply_trans: param malloc fail for %u "
    3305             :                                  "bytes !\n", (unsigned int)state->total_param));
    3306           0 :                         SAFE_FREE(state->data);
    3307           0 :                         TALLOC_FREE(state);
    3308           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    3309           0 :                         END_PROFILE(SMBtrans2);
    3310           0 :                         return;
    3311             :                 }
    3312             : 
    3313           8 :                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
    3314             :         }
    3315             : 
    3316           8 :         state->received_data  = dscnt;
    3317           8 :         state->received_param = pscnt;
    3318             : 
    3319          12 :         if ((state->received_param == state->total_param) &&
    3320           8 :             (state->received_data == state->total_data)) {
    3321             : 
    3322           8 :                 handle_trans2(conn, req, state);
    3323             : 
    3324           8 :                 SAFE_FREE(state->data);
    3325           8 :                 SAFE_FREE(state->param);
    3326           8 :                 TALLOC_FREE(state);
    3327           8 :                 END_PROFILE(SMBtrans2);
    3328           8 :                 return;
    3329             :         }
    3330             : 
    3331           0 :         DLIST_ADD(conn->pending_trans, state);
    3332             : 
    3333             :         /* We need to send an interim response then receive the rest
    3334             :            of the parameter/data bytes */
    3335           0 :         reply_smb1_outbuf(req, 0, 0);
    3336           0 :         show_msg((char *)req->outbuf);
    3337           0 :         END_PROFILE(SMBtrans2);
    3338           0 :         return;
    3339             : 
    3340           0 :   bad_param:
    3341             : 
    3342           0 :         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
    3343           0 :         SAFE_FREE(state->data);
    3344           0 :         SAFE_FREE(state->param);
    3345           0 :         TALLOC_FREE(state);
    3346           0 :         END_PROFILE(SMBtrans2);
    3347           0 :         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    3348             : }
    3349             : 
    3350             : /****************************************************************************
    3351             :  Reply to a SMBtranss2
    3352             :  ****************************************************************************/
    3353             : 
    3354           0 : void reply_transs2(struct smb_request *req)
    3355             : {
    3356           0 :         connection_struct *conn = req->conn;
    3357             :         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
    3358             :         struct trans_state *state;
    3359             : 
    3360           0 :         START_PROFILE(SMBtranss2);
    3361             : 
    3362           0 :         show_msg((const char *)req->inbuf);
    3363             : 
    3364             :         /* Windows clients expect all replies to
    3365             :            a transact secondary (SMBtranss2 0x33)
    3366             :            to have a command code of transact
    3367             :            (SMBtrans2 0x32). See bug #8989
    3368             :            and also [MS-CIFS] section 2.2.4.47.2
    3369             :            for details.
    3370             :         */
    3371           0 :         req->cmd = SMBtrans2;
    3372             : 
    3373           0 :         if (req->wct < 8) {
    3374           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    3375           0 :                 END_PROFILE(SMBtranss2);
    3376           0 :                 return;
    3377             :         }
    3378             : 
    3379           0 :         for (state = conn->pending_trans; state != NULL;
    3380           0 :              state = state->next) {
    3381           0 :                 if (state->mid == req->mid) {
    3382           0 :                         break;
    3383             :                 }
    3384             :         }
    3385             : 
    3386           0 :         if ((state == NULL) || (state->cmd != SMBtrans2)) {
    3387           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    3388           0 :                 END_PROFILE(SMBtranss2);
    3389           0 :                 return;
    3390             :         }
    3391             : 
    3392             :         /* Revise state->total_param and state->total_data in case they have
    3393             :            changed downwards */
    3394             : 
    3395           0 :         if (SVAL(req->vwv+0, 0) < state->total_param)
    3396           0 :                 state->total_param = SVAL(req->vwv+0, 0);
    3397           0 :         if (SVAL(req->vwv+1, 0) < state->total_data)
    3398           0 :                 state->total_data = SVAL(req->vwv+1, 0);
    3399             : 
    3400           0 :         pcnt = SVAL(req->vwv+2, 0);
    3401           0 :         poff = SVAL(req->vwv+3, 0);
    3402           0 :         pdisp = SVAL(req->vwv+4, 0);
    3403             : 
    3404           0 :         dcnt = SVAL(req->vwv+5, 0);
    3405           0 :         doff = SVAL(req->vwv+6, 0);
    3406           0 :         ddisp = SVAL(req->vwv+7, 0);
    3407             : 
    3408           0 :         state->received_param += pcnt;
    3409           0 :         state->received_data += dcnt;
    3410             : 
    3411           0 :         if ((state->received_data > state->total_data) ||
    3412           0 :             (state->received_param > state->total_param))
    3413           0 :                 goto bad_param;
    3414             : 
    3415           0 :         if (pcnt) {
    3416           0 :                 if (smb_buffer_oob(state->total_param, pdisp, pcnt)
    3417           0 :                     || smb_buffer_oob(smb_len(req->inbuf), poff, pcnt)) {
    3418           0 :                         goto bad_param;
    3419             :                 }
    3420           0 :                 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
    3421             :         }
    3422             : 
    3423           0 :         if (dcnt) {
    3424           0 :                 if (smb_buffer_oob(state->total_data, ddisp, dcnt)
    3425           0 :                     || smb_buffer_oob(smb_len(req->inbuf), doff, dcnt)) {
    3426           0 :                         goto bad_param;
    3427             :                 }
    3428           0 :                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
    3429             :         }
    3430             : 
    3431           0 :         if ((state->received_param < state->total_param) ||
    3432           0 :             (state->received_data < state->total_data)) {
    3433           0 :                 END_PROFILE(SMBtranss2);
    3434           0 :                 return;
    3435             :         }
    3436             : 
    3437           0 :         handle_trans2(conn, req, state);
    3438             : 
    3439           0 :         DLIST_REMOVE(conn->pending_trans, state);
    3440           0 :         SAFE_FREE(state->data);
    3441           0 :         SAFE_FREE(state->param);
    3442           0 :         TALLOC_FREE(state);
    3443             : 
    3444           0 :         END_PROFILE(SMBtranss2);
    3445           0 :         return;
    3446             : 
    3447           0 :   bad_param:
    3448             : 
    3449           0 :         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
    3450           0 :         DLIST_REMOVE(conn->pending_trans, state);
    3451           0 :         SAFE_FREE(state->data);
    3452           0 :         SAFE_FREE(state->param);
    3453           0 :         TALLOC_FREE(state);
    3454           0 :         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    3455           0 :         END_PROFILE(SMBtranss2);
    3456           0 :         return;
    3457             : }

Generated by: LCOV version 1.13