I found lots of places where we assume error will be set when calling
[samba.git] / source3 / smbd / reply.c
1 /*
2    Unix SMB/CIFS implementation.
3    Main SMB reply routines
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett      2001
6    Copyright (C) Jeremy Allison 1992-2007.
7    Copyright (C) Volker Lendecke 2007
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 /*
23    This file handles most of the reply_ calls that the server
24    makes to handle specific protocols
25 */
26
27 #include "includes.h"
28
29 /* look in server.c for some explanation of these variables */
30 extern enum protocol_types Protocol;
31 extern int max_recv;
32 unsigned int smb_echo_count = 0;
33 extern uint32 global_client_caps;
34
35 extern bool global_encrypted_passwords_negotiated;
36
37 /****************************************************************************
38  Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
39  path or anything including wildcards.
40  We're assuming here that '/' is not the second byte in any multibyte char
41  set (a safe assumption). '\\' *may* be the second byte in a multibyte char
42  set.
43 ****************************************************************************/
44
45 /* Custom version for processing POSIX paths. */
46 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
47
48 static NTSTATUS check_path_syntax_internal(char *path,
49                                            bool posix_path,
50                                            bool *p_last_component_contains_wcard)
51 {
52         char *d = path;
53         const char *s = path;
54         NTSTATUS ret = NT_STATUS_OK;
55         bool start_of_name_component = True;
56
57         *p_last_component_contains_wcard = False;
58
59         while (*s) {
60                 if (IS_PATH_SEP(*s,posix_path)) {
61                         /*
62                          * Safe to assume is not the second part of a mb char
63                          * as this is handled below.
64                          */
65                         /* Eat multiple '/' or '\\' */
66                         while (IS_PATH_SEP(*s,posix_path)) {
67                                 s++;
68                         }
69                         if ((d != path) && (*s != '\0')) {
70                                 /* We only care about non-leading or trailing '/' or '\\' */
71                                 *d++ = '/';
72                         }
73
74                         start_of_name_component = True;
75                         /* New component. */
76                         *p_last_component_contains_wcard = False;
77                         continue;
78                 }
79
80                 if (start_of_name_component) {
81                         if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
82                                 /* Uh oh - "/../" or "\\..\\"  or "/..\0" or "\\..\0" ! */
83
84                                 /*
85                                  * No mb char starts with '.' so we're safe checking the directory separator here.
86                                  */
87
88                                 /* If  we just added a '/' - delete it */
89                                 if ((d > path) && (*(d-1) == '/')) {
90                                         *(d-1) = '\0';
91                                         d--;
92                                 }
93
94                                 /* Are we at the start ? Can't go back further if so. */
95                                 if (d <= path) {
96                                         ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
97                                         break;
98                                 }
99                                 /* Go back one level... */
100                                 /* We know this is safe as '/' cannot be part of a mb sequence. */
101                                 /* NOTE - if this assumption is invalid we are not in good shape... */
102                                 /* Decrement d first as d points to the *next* char to write into. */
103                                 for (d--; d > path; d--) {
104                                         if (*d == '/')
105                                                 break;
106                                 }
107                                 s += 2; /* Else go past the .. */
108                                 /* We're still at the start of a name component, just the previous one. */
109                                 continue;
110
111                         } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
112                                 if (posix_path) {
113                                         /* Eat the '.' */
114                                         s++;
115                                         continue;
116                                 }
117                         }
118
119                 }
120
121                 if (!(*s & 0x80)) {
122                         if (!posix_path) {
123                                 if (*s <= 0x1f) {
124                                         return NT_STATUS_OBJECT_NAME_INVALID;
125                                 }
126                                 switch (*s) {
127                                         case '*':
128                                         case '?':
129                                         case '<':
130                                         case '>':
131                                         case '"':
132                                                 *p_last_component_contains_wcard = True;
133                                                 break;
134                                         default:
135                                                 break;
136                                 }
137                         }
138                         *d++ = *s++;
139                 } else {
140                         size_t siz;
141                         /* Get the size of the next MB character. */
142                         next_codepoint(s,&siz);
143                         switch(siz) {
144                                 case 5:
145                                         *d++ = *s++;
146                                         /*fall through*/
147                                 case 4:
148                                         *d++ = *s++;
149                                         /*fall through*/
150                                 case 3:
151                                         *d++ = *s++;
152                                         /*fall through*/
153                                 case 2:
154                                         *d++ = *s++;
155                                         /*fall through*/
156                                 case 1:
157                                         *d++ = *s++;
158                                         break;
159                                 default:
160                                         DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
161                                         *d = '\0';
162                                         return NT_STATUS_INVALID_PARAMETER;
163                         }
164                 }
165                 start_of_name_component = False;
166         }
167
168         *d = '\0';
169
170         return ret;
171 }
172
173 /****************************************************************************
174  Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
175  No wildcards allowed.
176 ****************************************************************************/
177
178 NTSTATUS check_path_syntax(char *path)
179 {
180         bool ignore;
181         return check_path_syntax_internal(path, False, &ignore);
182 }
183
184 /****************************************************************************
185  Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
186  Wildcards allowed - p_contains_wcard returns true if the last component contained
187  a wildcard.
188 ****************************************************************************/
189
190 NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
191 {
192         return check_path_syntax_internal(path, False, p_contains_wcard);
193 }
194
195 /****************************************************************************
196  Check the path for a POSIX client.
197  We're assuming here that '/' is not the second byte in any multibyte char
198  set (a safe assumption).
199 ****************************************************************************/
200
201 NTSTATUS check_path_syntax_posix(char *path)
202 {
203         bool ignore;
204         return check_path_syntax_internal(path, True, &ignore);
205 }
206
207 /****************************************************************************
208  Pull a string and check the path allowing a wilcard - provide for error return.
209 ****************************************************************************/
210
211 size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
212                         const char *inbuf,
213                         uint16 smb_flags2,
214                         char **pp_dest,
215                         const char *src,
216                         size_t src_len,
217                         int flags,
218                         NTSTATUS *err,
219                         bool *contains_wcard)
220 {
221         size_t ret;
222
223         *pp_dest = NULL;
224
225         if (src_len == 0) {
226                 ret = srvstr_pull_buf_talloc(ctx,
227                                 inbuf,
228                                 smb_flags2,
229                                 pp_dest,
230                                 src,
231                                 flags);
232         } else {
233                 ret = srvstr_pull_talloc(ctx,
234                                 inbuf,
235                                 smb_flags2,
236                                 pp_dest,
237                                 src,
238                                 src_len,
239                                 flags);
240         }
241
242         if (!*pp_dest) {
243                 *err = NT_STATUS_INVALID_PARAMETER;
244                 return ret;
245         }
246
247         *contains_wcard = False;
248
249         if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
250                 /*
251                  * For a DFS path the function parse_dfs_path()
252                  * will do the path processing, just make a copy.
253                  */
254                 *err = NT_STATUS_OK;
255                 return ret;
256         }
257
258         if (lp_posix_pathnames()) {
259                 *err = check_path_syntax_posix(*pp_dest);
260         } else {
261                 *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
262         }
263
264         return ret;
265 }
266
267 /****************************************************************************
268  Pull a string and check the path - provide for error return.
269 ****************************************************************************/
270
271 size_t srvstr_get_path(TALLOC_CTX *ctx,
272                         const char *inbuf,
273                         uint16 smb_flags2,
274                         char **pp_dest,
275                         const char *src,
276                         size_t src_len,
277                         int flags,
278                         NTSTATUS *err)
279 {
280         size_t ret;
281
282         *pp_dest = NULL;
283
284         if (src_len == 0) {
285                 ret = srvstr_pull_buf_talloc(ctx,
286                                         inbuf,
287                                         smb_flags2,
288                                         pp_dest,
289                                         src,
290                                         flags);
291         } else {
292                 ret = srvstr_pull_talloc(ctx,
293                                 inbuf,
294                                 smb_flags2,
295                                 pp_dest,
296                                 src,
297                                 src_len,
298                                 flags);
299         }
300
301         if (!*pp_dest) {
302                 *err = NT_STATUS_INVALID_PARAMETER;
303                 return ret;
304         }
305
306         if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
307                 /*
308                  * For a DFS path the function parse_dfs_path()
309                  * will do the path processing, just make a copy.
310                  */
311                 *err = NT_STATUS_OK;
312                 return ret;
313         }
314
315         if (lp_posix_pathnames()) {
316                 *err = check_path_syntax_posix(*pp_dest);
317         } else {
318                 *err = check_path_syntax(*pp_dest);
319         }
320
321         return ret;
322 }
323
324 /****************************************************************************
325  Check if we have a correct fsp pointing to a file. Basic check for open fsp.
326 ****************************************************************************/
327
328 bool check_fsp_open(connection_struct *conn, struct smb_request *req,
329                     files_struct *fsp)
330 {
331         if (!(fsp) || !(conn)) {
332                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
333                 return False;
334         }
335         if (((conn) != (fsp)->conn) || req->vuid != (fsp)->vuid) {
336                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
337                 return False;
338         }
339         return True;
340 }
341
342 /****************************************************************************
343  Check if we have a correct fsp pointing to a file. Replacement for the
344  CHECK_FSP macro.
345 ****************************************************************************/
346
347 bool check_fsp(connection_struct *conn, struct smb_request *req,
348                files_struct *fsp)
349 {
350         if (!check_fsp_open(conn, req, fsp)) {
351                 return False;
352         }
353         if ((fsp)->is_directory) {
354                 reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
355                 return False;
356         }
357         if ((fsp)->fh->fd == -1) {
358                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
359                 return False;
360         }
361         (fsp)->num_smb_operations++;
362         return True;
363 }
364
365 /****************************************************************************
366  Check if we have a correct fsp pointing to a quota fake file. Replacement for
367  the CHECK_NTQUOTA_HANDLE_OK macro.
368 ****************************************************************************/
369
370 bool check_fsp_ntquota_handle(connection_struct *conn, struct smb_request *req,
371                               files_struct *fsp)
372 {
373         if (!check_fsp_open(conn, req, fsp)) {
374                 return false;
375         }
376
377         if (fsp->is_directory) {
378                 return false;
379         }
380
381         if (fsp->fake_file_handle == NULL) {
382                 return false;
383         }
384
385         if (fsp->fake_file_handle->type != FAKE_FILE_TYPE_QUOTA) {
386                 return false;
387         }
388
389         if (fsp->fake_file_handle->private_data == NULL) {
390                 return false;
391         }
392
393         return true;
394 }
395
396 /****************************************************************************
397  Check if we have a correct fsp. Replacement for the FSP_BELONGS_CONN macro
398 ****************************************************************************/
399
400 bool fsp_belongs_conn(connection_struct *conn, struct smb_request *req,
401                       files_struct *fsp)
402 {
403         if ((fsp) && (conn) && ((conn)==(fsp)->conn)
404             && (req->vuid == (fsp)->vuid)) {
405                 return True;
406         }
407
408         reply_nterror(req, NT_STATUS_INVALID_HANDLE);
409         return False;
410 }
411
412 /****************************************************************************
413  Reply to a (netbios-level) special message.
414 ****************************************************************************/
415
416 void reply_special(char *inbuf)
417 {
418         int msg_type = CVAL(inbuf,0);
419         int msg_flags = CVAL(inbuf,1);
420         fstring name1,name2;
421         char name_type = 0;
422
423         /*
424          * We only really use 4 bytes of the outbuf, but for the smb_setlen
425          * calculation & friends (srv_send_smb uses that) we need the full smb
426          * header.
427          */
428         char outbuf[smb_size];
429         
430         static bool already_got_session = False;
431
432         *name1 = *name2 = 0;
433         
434         memset(outbuf, '\0', sizeof(outbuf));
435
436         smb_setlen(outbuf,0);
437         
438         switch (msg_type) {
439         case 0x81: /* session request */
440                 
441                 if (already_got_session) {
442                         exit_server_cleanly("multiple session request not permitted");
443                 }
444                 
445                 SCVAL(outbuf,0,0x82);
446                 SCVAL(outbuf,3,0);
447                 if (name_len(inbuf+4) > 50 || 
448                     name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
449                         DEBUG(0,("Invalid name length in session request\n"));
450                         return;
451                 }
452                 name_extract(inbuf,4,name1);
453                 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
454                 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
455                          name1,name2));      
456
457                 set_local_machine_name(name1, True);
458                 set_remote_machine_name(name2, True);
459
460                 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
461                          get_local_machine_name(), get_remote_machine_name(),
462                          name_type));
463
464                 if (name_type == 'R') {
465                         /* We are being asked for a pathworks session --- 
466                            no thanks! */
467                         SCVAL(outbuf, 0,0x83);
468                         break;
469                 }
470
471                 /* only add the client's machine name to the list
472                    of possibly valid usernames if we are operating
473                    in share mode security */
474                 if (lp_security() == SEC_SHARE) {
475                         add_session_user(get_remote_machine_name());
476                 }
477
478                 reload_services(True);
479                 reopen_logs();
480
481                 already_got_session = True;
482                 break;
483                 
484         case 0x89: /* session keepalive request 
485                       (some old clients produce this?) */
486                 SCVAL(outbuf,0,SMBkeepalive);
487                 SCVAL(outbuf,3,0);
488                 break;
489                 
490         case 0x82: /* positive session response */
491         case 0x83: /* negative session response */
492         case 0x84: /* retarget session response */
493                 DEBUG(0,("Unexpected session response\n"));
494                 break;
495                 
496         case SMBkeepalive: /* session keepalive */
497         default:
498                 return;
499         }
500         
501         DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
502                     msg_type, msg_flags));
503
504         srv_send_smb(smbd_server_fd(), outbuf, false);
505         return;
506 }
507
508 /****************************************************************************
509  Reply to a tcon.
510  conn POINTER CAN BE NULL HERE !
511 ****************************************************************************/
512
513 void reply_tcon(struct smb_request *req)
514 {
515         connection_struct *conn = req->conn;
516         const char *service;
517         char *service_buf = NULL;
518         char *password = NULL;
519         char *dev = NULL;
520         int pwlen=0;
521         NTSTATUS nt_status;
522         char *p;
523         DATA_BLOB password_blob;
524         TALLOC_CTX *ctx = talloc_tos();
525
526         START_PROFILE(SMBtcon);
527
528         if (smb_buflen(req->inbuf) < 4) {
529                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
530                 END_PROFILE(SMBtcon);
531                 return;
532         }
533
534         p = smb_buf(req->inbuf)+1;
535         p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
536                                     &service_buf, p, STR_TERMINATE) + 1;
537         pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
538                                        &password, p, STR_TERMINATE) + 1;
539         p += pwlen;
540         p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
541                                     &dev, p, STR_TERMINATE) + 1;
542
543         if (service_buf == NULL || password == NULL || dev == NULL) {
544                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
545                 END_PROFILE(SMBtcon);
546                 return;
547         }
548         p = strrchr_m(service_buf,'\\');
549         if (p) {
550                 service = p+1;
551         } else {
552                 service = service_buf;
553         }
554
555         password_blob = data_blob(password, pwlen+1);
556
557         conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
558         req->conn = conn;
559
560         data_blob_clear_free(&password_blob);
561
562         if (!conn) {
563                 reply_nterror(req, nt_status);
564                 END_PROFILE(SMBtcon);
565                 return;
566         }
567
568         reply_outbuf(req, 2, 0);
569         SSVAL(req->outbuf,smb_vwv0,max_recv);
570         SSVAL(req->outbuf,smb_vwv1,conn->cnum);
571         SSVAL(req->outbuf,smb_tid,conn->cnum);
572
573         DEBUG(3,("tcon service=%s cnum=%d\n",
574                  service, conn->cnum));
575
576         END_PROFILE(SMBtcon);
577         return;
578 }
579
580 /****************************************************************************
581  Reply to a tcon and X.
582  conn POINTER CAN BE NULL HERE !
583 ****************************************************************************/
584
585 void reply_tcon_and_X(struct smb_request *req)
586 {
587         connection_struct *conn = req->conn;
588         char *service = NULL;
589         DATA_BLOB password;
590         TALLOC_CTX *ctx = talloc_tos();
591         /* what the cleint thinks the device is */
592         char *client_devicetype = NULL;
593         /* what the server tells the client the share represents */
594         const char *server_devicetype;
595         NTSTATUS nt_status;
596         int passlen;
597         char *path = NULL;
598         char *p, *q;
599         uint16 tcon_flags;
600
601         START_PROFILE(SMBtconX);
602
603         if (req->wct < 4) {
604                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
605                 END_PROFILE(SMBtconX);
606                 return;
607         }
608
609         passlen = SVAL(req->inbuf,smb_vwv3);
610         tcon_flags = SVAL(req->inbuf,smb_vwv2);
611
612         /* we might have to close an old one */
613         if ((tcon_flags & 0x1) && conn) {
614                 close_cnum(conn,req->vuid);
615                 req->conn = NULL;
616                 conn = NULL;
617         }
618
619         if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
620                 reply_doserror(req, ERRDOS, ERRbuftoosmall);
621                 END_PROFILE(SMBtconX);
622                 return;
623         }
624
625         if (global_encrypted_passwords_negotiated) {
626                 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
627                                             passlen);
628                 if (lp_security() == SEC_SHARE) {
629                         /*
630                          * Security = share always has a pad byte
631                          * after the password.
632                          */
633                         p = smb_buf(req->inbuf) + passlen + 1;
634                 } else {
635                         p = smb_buf(req->inbuf) + passlen;
636                 }
637         } else {
638                 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
639                                             passlen+1);
640                 /* Ensure correct termination */
641                 password.data[passlen]=0;
642                 p = smb_buf(req->inbuf) + passlen + 1;
643         }
644
645         p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
646                              STR_TERMINATE);
647
648         if (path == NULL) {
649                 data_blob_clear_free(&password);
650                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
651                 END_PROFILE(SMBtconX);
652                 return;
653         }
654
655         /*
656          * the service name can be either: \\server\share
657          * or share directly like on the DELL PowerVault 705
658          */
659         if (*path=='\\') {
660                 q = strchr_m(path+2,'\\');
661                 if (!q) {
662                         data_blob_clear_free(&password);
663                         reply_doserror(req, ERRDOS, ERRnosuchshare);
664                         END_PROFILE(SMBtconX);
665                         return;
666                 }
667                 service = q+1;
668         } else {
669                 service = path;
670         }
671
672         p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
673                                 &client_devicetype, p,
674                                 MIN(6,smb_bufrem(req->inbuf, p)), STR_ASCII);
675
676         if (client_devicetype == NULL) {
677                 data_blob_clear_free(&password);
678                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
679                 END_PROFILE(SMBtconX);
680                 return;
681         }
682
683         DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
684
685         conn = make_connection(service, password, client_devicetype,
686                                req->vuid, &nt_status);
687         req->conn =conn;
688
689         data_blob_clear_free(&password);
690
691         if (!conn) {
692                 reply_nterror(req, nt_status);
693                 END_PROFILE(SMBtconX);
694                 return;
695         }
696
697         if ( IS_IPC(conn) )
698                 server_devicetype = "IPC";
699         else if ( IS_PRINT(conn) )
700                 server_devicetype = "LPT1:";
701         else
702                 server_devicetype = "A:";
703
704         if (Protocol < PROTOCOL_NT1) {
705                 reply_outbuf(req, 2, 0);
706                 if (message_push_string(&req->outbuf, server_devicetype,
707                                         STR_TERMINATE|STR_ASCII) == -1) {
708                         reply_nterror(req, NT_STATUS_NO_MEMORY);
709                         END_PROFILE(SMBtconX);
710                         return;
711                 }
712         } else {
713                 /* NT sets the fstype of IPC$ to the null string */
714                 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
715
716                 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
717                         /* Return permissions. */
718                         uint32 perm1 = 0;
719                         uint32 perm2 = 0;
720
721                         reply_outbuf(req, 7, 0);
722
723                         if (IS_IPC(conn)) {
724                                 perm1 = FILE_ALL_ACCESS;
725                                 perm2 = FILE_ALL_ACCESS;
726                         } else {
727                                 perm1 = CAN_WRITE(conn) ?
728                                                 SHARE_ALL_ACCESS :
729                                                 SHARE_READ_ONLY;
730                         }
731
732                         SIVAL(req->outbuf, smb_vwv3, perm1);
733                         SIVAL(req->outbuf, smb_vwv5, perm2);
734                 } else {
735                         reply_outbuf(req, 3, 0);
736                 }
737
738                 if ((message_push_string(&req->outbuf, server_devicetype,
739                                          STR_TERMINATE|STR_ASCII) == -1)
740                     || (message_push_string(&req->outbuf, fstype,
741                                             STR_TERMINATE) == -1)) {
742                         reply_nterror(req, NT_STATUS_NO_MEMORY);
743                         END_PROFILE(SMBtconX);
744                         return;
745                 }
746
747                 /* what does setting this bit do? It is set by NT4 and
748                    may affect the ability to autorun mounted cdroms */
749                 SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
750                       (lp_csc_policy(SNUM(conn)) << 2));
751
752                 init_dfsroot(conn, req->inbuf, req->outbuf);
753         }
754
755
756         DEBUG(3,("tconX service=%s \n",
757                  service));
758
759         /* set the incoming and outgoing tid to the just created one */
760         SSVAL(req->inbuf,smb_tid,conn->cnum);
761         SSVAL(req->outbuf,smb_tid,conn->cnum);
762
763         END_PROFILE(SMBtconX);
764
765         chain_reply(req);
766         return;
767 }
768
769 /****************************************************************************
770  Reply to an unknown type.
771 ****************************************************************************/
772
773 void reply_unknown_new(struct smb_request *req, uint8 type)
774 {
775         DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
776                   smb_fn_name(type), type, type));
777         reply_doserror(req, ERRSRV, ERRunknownsmb);
778         return;
779 }
780
781 /****************************************************************************
782  Reply to an ioctl.
783  conn POINTER CAN BE NULL HERE !
784 ****************************************************************************/
785
786 void reply_ioctl(struct smb_request *req)
787 {
788         connection_struct *conn = req->conn;
789         uint16 device;
790         uint16 function;
791         uint32 ioctl_code;
792         int replysize;
793         char *p;
794
795         START_PROFILE(SMBioctl);
796
797         if (req->wct < 3) {
798                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
799                 END_PROFILE(SMBioctl);
800                 return;
801         }
802
803         device     = SVAL(req->inbuf,smb_vwv1);
804         function   = SVAL(req->inbuf,smb_vwv2);
805         ioctl_code = (device << 16) + function;
806
807         DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
808
809         switch (ioctl_code) {
810             case IOCTL_QUERY_JOB_INFO:
811                     replysize = 32;
812                     break;
813             default:
814                     reply_doserror(req, ERRSRV, ERRnosupport);
815                     END_PROFILE(SMBioctl);
816                     return;
817         }
818
819         reply_outbuf(req, 8, replysize+1);
820         SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
821         SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
822         SSVAL(req->outbuf,smb_vwv6,52);        /* Offset to data */
823         p = smb_buf(req->outbuf);
824         memset(p, '\0', replysize+1); /* valgrind-safe. */
825         p += 1;          /* Allow for alignment */
826
827         switch (ioctl_code) {
828                 case IOCTL_QUERY_JOB_INFO:                  
829                 {
830                         files_struct *fsp = file_fsp(SVAL(req->inbuf,
831                                                           smb_vwv0));
832                         if (!fsp) {
833                                 reply_doserror(req, ERRDOS, ERRbadfid);
834                                 END_PROFILE(SMBioctl);
835                                 return;
836                         }
837                         SSVAL(p,0,fsp->rap_print_jobid);             /* Job number */
838                         srvstr_push((char *)req->outbuf, req->flags2, p+2,
839                                     global_myname(), 15,
840                                     STR_TERMINATE|STR_ASCII);
841                         if (conn) {
842                                 srvstr_push((char *)req->outbuf, req->flags2,
843                                             p+18, lp_servicename(SNUM(conn)),
844                                             13, STR_TERMINATE|STR_ASCII);
845                         } else {
846                                 memset(p+18, 0, 13);
847                         }
848                         break;
849                 }
850         }
851
852         END_PROFILE(SMBioctl);
853         return;
854 }
855
856 /****************************************************************************
857  Strange checkpath NTSTATUS mapping.
858 ****************************************************************************/
859
860 static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
861 {
862         /* Strange DOS error code semantics only for checkpath... */
863         if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
864                 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
865                         /* We need to map to ERRbadpath */
866                         return NT_STATUS_OBJECT_PATH_NOT_FOUND;
867                 }
868         }
869         return status;
870 }
871
872 /****************************************************************************
873  Reply to a checkpath.
874 ****************************************************************************/
875
876 void reply_checkpath(struct smb_request *req)
877 {
878         connection_struct *conn = req->conn;
879         char *name = NULL;
880         SMB_STRUCT_STAT sbuf;
881         NTSTATUS status;
882         TALLOC_CTX *ctx = talloc_tos();
883
884         START_PROFILE(SMBcheckpath);
885
886         srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
887                         smb_buf(req->inbuf) + 1, 0,
888                         STR_TERMINATE, &status);
889         if (!NT_STATUS_IS_OK(status)) {
890                 status = map_checkpath_error((char *)req->inbuf, status);
891                 reply_nterror(req, status);
892                 END_PROFILE(SMBcheckpath);
893                 return;
894         }
895
896         status = resolve_dfspath(ctx, conn,
897                         req->flags2 & FLAGS2_DFS_PATHNAMES,
898                         name,
899                         &name);
900         if (!NT_STATUS_IS_OK(status)) {
901                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
902                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
903                                         ERRSRV, ERRbadpath);
904                         END_PROFILE(SMBcheckpath);
905                         return;
906                 }
907                 goto path_err;
908         }
909
910         DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
911
912         status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
913         if (!NT_STATUS_IS_OK(status)) {
914                 goto path_err;
915         }
916
917         status = check_name(conn, name);
918         if (!NT_STATUS_IS_OK(status)) {
919                 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status)));
920                 goto path_err;
921         }
922
923         if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
924                 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
925                 status = map_nt_error_from_unix(errno);
926                 goto path_err;
927         }
928
929         if (!S_ISDIR(sbuf.st_mode)) {
930                 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
931                                 ERRDOS, ERRbadpath);
932                 END_PROFILE(SMBcheckpath);
933                 return;
934         }
935
936         reply_outbuf(req, 0, 0);
937
938         END_PROFILE(SMBcheckpath);
939         return;
940
941   path_err:
942
943         END_PROFILE(SMBcheckpath);
944
945         /* We special case this - as when a Windows machine
946                 is parsing a path is steps through the components
947                 one at a time - if a component fails it expects
948                 ERRbadpath, not ERRbadfile.
949         */
950         status = map_checkpath_error((char *)req->inbuf, status);
951         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
952                 /*
953                  * Windows returns different error codes if
954                  * the parent directory is valid but not the
955                  * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
956                  * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
957                  * if the path is invalid.
958                  */
959                 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
960                                 ERRDOS, ERRbadpath);
961                 return;
962         }
963
964         reply_nterror(req, status);
965 }
966
967 /****************************************************************************
968  Reply to a getatr.
969 ****************************************************************************/
970
971 void reply_getatr(struct smb_request *req)
972 {
973         connection_struct *conn = req->conn;
974         char *fname = NULL;
975         SMB_STRUCT_STAT sbuf;
976         int mode=0;
977         SMB_OFF_T size=0;
978         time_t mtime=0;
979         char *p;
980         NTSTATUS status;
981         TALLOC_CTX *ctx = talloc_tos();
982
983         START_PROFILE(SMBgetatr);
984
985         p = smb_buf(req->inbuf) + 1;
986         p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
987                              0, STR_TERMINATE, &status);
988         if (!NT_STATUS_IS_OK(status)) {
989                 reply_nterror(req, status);
990                 END_PROFILE(SMBgetatr);
991                 return;
992         }
993
994         status = resolve_dfspath(ctx, conn,
995                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
996                                 fname,
997                                 &fname);
998         if (!NT_STATUS_IS_OK(status)) {
999                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1000                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1001                                         ERRSRV, ERRbadpath);
1002                         END_PROFILE(SMBgetatr);
1003                         return;
1004                 }
1005                 reply_nterror(req, status);
1006                 END_PROFILE(SMBgetatr);
1007                 return;
1008         }
1009
1010         /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1011                 under WfWg - weird! */
1012         if (*fname == '\0') {
1013                 mode = aHIDDEN | aDIR;
1014                 if (!CAN_WRITE(conn)) {
1015                         mode |= aRONLY;
1016                 }
1017                 size = 0;
1018                 mtime = 0;
1019         } else {
1020                 status = unix_convert(ctx, conn, fname, False, &fname, NULL,&sbuf);
1021                 if (!NT_STATUS_IS_OK(status)) {
1022                         reply_nterror(req, status);
1023                         END_PROFILE(SMBgetatr);
1024                         return;
1025                 }
1026                 status = check_name(conn, fname);
1027                 if (!NT_STATUS_IS_OK(status)) {
1028                         DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
1029                         reply_nterror(req, status);
1030                         END_PROFILE(SMBgetatr);
1031                         return;
1032                 }
1033                 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
1034                         DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
1035                         reply_unixerror(req, ERRDOS,ERRbadfile);
1036                         END_PROFILE(SMBgetatr);
1037                         return;
1038                 }
1039
1040                 mode = dos_mode(conn,fname,&sbuf);
1041                 size = sbuf.st_size;
1042                 mtime = sbuf.st_mtime;
1043                 if (mode & aDIR) {
1044                         size = 0;
1045                 }
1046         }
1047
1048         reply_outbuf(req, 10, 0);
1049
1050         SSVAL(req->outbuf,smb_vwv0,mode);
1051         if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1052                 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1053         } else {
1054                 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1055         }
1056         SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1057
1058         if (Protocol >= PROTOCOL_NT1) {
1059                 SSVAL(req->outbuf, smb_flg2,
1060                       SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1061         }
1062   
1063         DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
1064
1065         END_PROFILE(SMBgetatr);
1066         return;
1067 }
1068
1069 /****************************************************************************
1070  Reply to a setatr.
1071 ****************************************************************************/
1072
1073 void reply_setatr(struct smb_request *req)
1074 {
1075         struct timespec ts[2];
1076         connection_struct *conn = req->conn;
1077         char *fname = NULL;
1078         int mode;
1079         time_t mtime;
1080         SMB_STRUCT_STAT sbuf;
1081         char *p;
1082         NTSTATUS status;
1083         TALLOC_CTX *ctx = talloc_tos();
1084
1085         START_PROFILE(SMBsetatr);
1086
1087         ZERO_STRUCT(ts);
1088
1089         if (req->wct < 2) {
1090                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1091                 return;
1092         }
1093
1094         p = smb_buf(req->inbuf) + 1;
1095         p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
1096                                 0, STR_TERMINATE, &status);
1097         if (!NT_STATUS_IS_OK(status)) {
1098                 reply_nterror(req, status);
1099                 END_PROFILE(SMBsetatr);
1100                 return;
1101         }
1102
1103         status = resolve_dfspath(ctx, conn,
1104                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
1105                                 fname,
1106                                 &fname);
1107         if (!NT_STATUS_IS_OK(status)) {
1108                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1109                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1110                                         ERRSRV, ERRbadpath);
1111                         END_PROFILE(SMBsetatr);
1112                         return;
1113                 }
1114                 reply_nterror(req, status);
1115                 END_PROFILE(SMBsetatr);
1116                 return;
1117         }
1118
1119         status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
1120         if (!NT_STATUS_IS_OK(status)) {
1121                 reply_nterror(req, status);
1122                 END_PROFILE(SMBsetatr);
1123                 return;
1124         }
1125
1126         status = check_name(conn, fname);
1127         if (!NT_STATUS_IS_OK(status)) {
1128                 reply_nterror(req, status);
1129                 END_PROFILE(SMBsetatr);
1130                 return;
1131         }
1132
1133         if (fname[0] == '.' && fname[1] == '\0') {
1134                 /*
1135                  * Not sure here is the right place to catch this
1136                  * condition. Might be moved to somewhere else later -- vl
1137                  */
1138                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1139                 END_PROFILE(SMBsetatr);
1140                 return;
1141         }
1142
1143         mode = SVAL(req->inbuf,smb_vwv0);
1144         mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
1145
1146         ts[1] = convert_time_t_to_timespec(mtime);
1147         status = smb_set_file_time(conn, NULL, fname,
1148                                    &sbuf, ts, true);
1149         if (!NT_STATUS_IS_OK(status)) {
1150                 reply_unixerror(req, ERRDOS, ERRnoaccess);
1151                 END_PROFILE(SMBsetatr);
1152                 return;
1153         }
1154
1155         if (mode != FILE_ATTRIBUTE_NORMAL) {
1156                 if (VALID_STAT_OF_DIR(sbuf))
1157                         mode |= aDIR;
1158                 else
1159                         mode &= ~aDIR;
1160
1161                 if (file_set_dosmode(conn,fname,mode,&sbuf,NULL,false) != 0) {
1162                         reply_unixerror(req, ERRDOS, ERRnoaccess);
1163                         END_PROFILE(SMBsetatr);
1164                         return;
1165                 }
1166         }
1167
1168         reply_outbuf(req, 0, 0);
1169  
1170         DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1171   
1172         END_PROFILE(SMBsetatr);
1173         return;
1174 }
1175
1176 /****************************************************************************
1177  Reply to a dskattr.
1178 ****************************************************************************/
1179
1180 void reply_dskattr(struct smb_request *req)
1181 {
1182         connection_struct *conn = req->conn;
1183         SMB_BIG_UINT dfree,dsize,bsize;
1184         START_PROFILE(SMBdskattr);
1185
1186         if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
1187                 reply_unixerror(req, ERRHRD, ERRgeneral);
1188                 END_PROFILE(SMBdskattr);
1189                 return;
1190         }
1191
1192         reply_outbuf(req, 5, 0);
1193         
1194         if (Protocol <= PROTOCOL_LANMAN2) {
1195                 double total_space, free_space;
1196                 /* we need to scale this to a number that DOS6 can handle. We
1197                    use floating point so we can handle large drives on systems
1198                    that don't have 64 bit integers 
1199
1200                    we end up displaying a maximum of 2G to DOS systems
1201                 */
1202                 total_space = dsize * (double)bsize;
1203                 free_space = dfree * (double)bsize;
1204
1205                 dsize = (SMB_BIG_UINT)((total_space+63*512) / (64*512));
1206                 dfree = (SMB_BIG_UINT)((free_space+63*512) / (64*512));
1207                 
1208                 if (dsize > 0xFFFF) dsize = 0xFFFF;
1209                 if (dfree > 0xFFFF) dfree = 0xFFFF;
1210
1211                 SSVAL(req->outbuf,smb_vwv0,dsize);
1212                 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1213                 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1214                 SSVAL(req->outbuf,smb_vwv3,dfree);
1215         } else {
1216                 SSVAL(req->outbuf,smb_vwv0,dsize);
1217                 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1218                 SSVAL(req->outbuf,smb_vwv2,512);
1219                 SSVAL(req->outbuf,smb_vwv3,dfree);
1220         }
1221
1222         DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1223
1224         END_PROFILE(SMBdskattr);
1225         return;
1226 }
1227
1228 /****************************************************************************
1229  Reply to a search.
1230  Can be called from SMBsearch, SMBffirst or SMBfunique.
1231 ****************************************************************************/
1232
1233 void reply_search(struct smb_request *req)
1234 {
1235         connection_struct *conn = req->conn;
1236         char *mask = NULL;
1237         char *directory = NULL;
1238         char *fname = NULL;
1239         SMB_OFF_T size;
1240         uint32 mode;
1241         time_t date;
1242         uint32 dirtype;
1243         unsigned int numentries = 0;
1244         unsigned int maxentries = 0;
1245         bool finished = False;
1246         char *p;
1247         int status_len;
1248         char *path = NULL;
1249         char status[21];
1250         int dptr_num= -1;
1251         bool check_descend = False;
1252         bool expect_close = False;
1253         NTSTATUS nt_status;
1254         bool mask_contains_wcard = False;
1255         bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1256         TALLOC_CTX *ctx = talloc_tos();
1257         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1258
1259         START_PROFILE(SMBsearch);
1260
1261         if (req->wct < 2) {
1262                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1263                 END_PROFILE(SMBsearch);
1264                 return;
1265         }
1266
1267         if (lp_posix_pathnames()) {
1268                 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1269                 END_PROFILE(SMBsearch);
1270                 return;
1271         }
1272
1273         /* If we were called as SMBffirst then we must expect close. */
1274         if(CVAL(req->inbuf,smb_com) == SMBffirst) {
1275                 expect_close = True;
1276         }
1277
1278         reply_outbuf(req, 1, 3);
1279         maxentries = SVAL(req->inbuf,smb_vwv0);
1280         dirtype = SVAL(req->inbuf,smb_vwv1);
1281         p = smb_buf(req->inbuf) + 1;
1282         p += srvstr_get_path_wcard(ctx,
1283                                 (char *)req->inbuf,
1284                                 req->flags2,
1285                                 &path,
1286                                 p,
1287                                 0,
1288                                 STR_TERMINATE,
1289                                 &nt_status,
1290                                 &mask_contains_wcard);
1291         if (!NT_STATUS_IS_OK(nt_status)) {
1292                 reply_nterror(req, nt_status);
1293                 END_PROFILE(SMBsearch);
1294                 return;
1295         }
1296
1297         nt_status = resolve_dfspath_wcard(ctx, conn,
1298                                           req->flags2 & FLAGS2_DFS_PATHNAMES,
1299                                           path,
1300                                           &path,
1301                                           &mask_contains_wcard);
1302         if (!NT_STATUS_IS_OK(nt_status)) {
1303                 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1304                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1305                                         ERRSRV, ERRbadpath);
1306                         END_PROFILE(SMBsearch);
1307                         return;
1308                 }
1309                 reply_nterror(req, nt_status);
1310                 END_PROFILE(SMBsearch);
1311                 return;
1312         }
1313
1314         p++;
1315         status_len = SVAL(p, 0);
1316         p += 2;
1317
1318         /* dirtype &= ~aDIR; */
1319
1320         if (status_len == 0) {
1321                 SMB_STRUCT_STAT sbuf;
1322
1323                 nt_status = unix_convert(ctx, conn, path, True,
1324                                 &directory, NULL, &sbuf);
1325                 if (!NT_STATUS_IS_OK(nt_status)) {
1326                         reply_nterror(req, nt_status);
1327                         END_PROFILE(SMBsearch);
1328                         return;
1329                 }
1330
1331                 nt_status = check_name(conn, directory);
1332                 if (!NT_STATUS_IS_OK(nt_status)) {
1333                         reply_nterror(req, nt_status);
1334                         END_PROFILE(SMBsearch);
1335                         return;
1336                 }
1337
1338                 p = strrchr_m(directory,'/');
1339                 if (!p) {
1340                         mask = directory;
1341                         directory = talloc_strdup(ctx,".");
1342                         if (!directory) {
1343                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1344                                 END_PROFILE(SMBsearch);
1345                                 return;
1346                         }
1347                 } else {
1348                         *p = 0;
1349                         mask = p+1;
1350                 }
1351
1352                 if (*directory == '\0') {
1353                         directory = talloc_strdup(ctx,".");
1354                         if (!directory) {
1355                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1356                                 END_PROFILE(SMBsearch);
1357                                 return;
1358                         }
1359                 }
1360                 memset((char *)status,'\0',21);
1361                 SCVAL(status,0,(dirtype & 0x1F));
1362
1363                 nt_status = dptr_create(conn,
1364                                         directory,
1365                                         True,
1366                                         expect_close,
1367                                         req->smbpid,
1368                                         mask,
1369                                         mask_contains_wcard,
1370                                         dirtype,
1371                                         &conn->dirptr);
1372                 if (!NT_STATUS_IS_OK(nt_status)) {
1373                         reply_nterror(req, nt_status);
1374                         END_PROFILE(SMBsearch);
1375                         return;
1376                 }
1377                 dptr_num = dptr_dnum(conn->dirptr);
1378         } else {
1379                 int status_dirtype;
1380
1381                 memcpy(status,p,21);
1382                 status_dirtype = CVAL(status,0) & 0x1F;
1383                 if (status_dirtype != (dirtype & 0x1F)) {
1384                         dirtype = status_dirtype;
1385                 }
1386
1387                 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1388                 if (!conn->dirptr) {
1389                         goto SearchEmpty;
1390                 }
1391                 string_set(&conn->dirpath,dptr_path(dptr_num));
1392                 mask = dptr_wcard(dptr_num);
1393                 if (!mask) {
1394                         goto SearchEmpty;
1395                 }
1396                 /*
1397                  * For a 'continue' search we have no string. So
1398                  * check from the initial saved string.
1399                  */
1400                 mask_contains_wcard = ms_has_wild(mask);
1401                 dirtype = dptr_attr(dptr_num);
1402         }
1403
1404         DEBUG(4,("dptr_num is %d\n",dptr_num));
1405
1406         if ((dirtype&0x1F) == aVOLID) {
1407                 char buf[DIR_STRUCT_SIZE];
1408                 memcpy(buf,status,21);
1409                 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1410                                 0,aVOLID,0,!allow_long_path_components)) {
1411                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1412                         END_PROFILE(SMBsearch);
1413                         return;
1414                 }
1415                 dptr_fill(buf+12,dptr_num);
1416                 if (dptr_zero(buf+12) && (status_len==0)) {
1417                         numentries = 1;
1418                 } else {
1419                         numentries = 0;
1420                 }
1421                 if (message_push_blob(&req->outbuf,
1422                                       data_blob_const(buf, sizeof(buf)))
1423                     == -1) {
1424                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1425                         END_PROFILE(SMBsearch);
1426                         return;
1427                 }
1428         } else {
1429                 unsigned int i;
1430                 maxentries = MIN(
1431                         maxentries,
1432                         ((BUFFER_SIZE -
1433                           ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1434                          /DIR_STRUCT_SIZE));
1435
1436                 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1437                         conn->dirpath,lp_dontdescend(SNUM(conn))));
1438                 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) {
1439                         check_descend = True;
1440                 }
1441
1442                 for (i=numentries;(i<maxentries) && !finished;i++) {
1443                         finished = !get_dir_entry(ctx,
1444                                                   conn,
1445                                                   mask,
1446                                                   dirtype,
1447                                                   &fname,
1448                                                   &size,
1449                                                   &mode,
1450                                                   &date,
1451                                                   check_descend,
1452                                                   ask_sharemode);
1453                         if (!finished) {
1454                                 char buf[DIR_STRUCT_SIZE];
1455                                 memcpy(buf,status,21);
1456                                 if (!make_dir_struct(ctx,
1457                                                 buf,
1458                                                 mask,
1459                                                 fname,
1460                                                 size,
1461                                                 mode,
1462                                                 date,
1463                                                 !allow_long_path_components)) {
1464                                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1465                                         END_PROFILE(SMBsearch);
1466                                         return;
1467                                 }
1468                                 if (!dptr_fill(buf+12,dptr_num)) {
1469                                         break;
1470                                 }
1471                                 if (message_push_blob(&req->outbuf,
1472                                                       data_blob_const(buf, sizeof(buf)))
1473                                     == -1) {
1474                                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1475                                         END_PROFILE(SMBsearch);
1476                                         return;
1477                                 }
1478                                 numentries++;
1479                         }
1480                 }
1481         }
1482
1483   SearchEmpty:
1484
1485         /* If we were called as SMBffirst with smb_search_id == NULL
1486                 and no entries were found then return error and close dirptr 
1487                 (X/Open spec) */
1488
1489         if (numentries == 0) {
1490                 dptr_close(&dptr_num);
1491         } else if(expect_close && status_len == 0) {
1492                 /* Close the dptr - we know it's gone */
1493                 dptr_close(&dptr_num);
1494         }
1495
1496         /* If we were called as SMBfunique, then we can close the dirptr now ! */
1497         if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
1498                 dptr_close(&dptr_num);
1499         }
1500
1501         if ((numentries == 0) && !mask_contains_wcard) {
1502                 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1503                 END_PROFILE(SMBsearch);
1504                 return;
1505         }
1506
1507         SSVAL(req->outbuf,smb_vwv0,numentries);
1508         SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1509         SCVAL(smb_buf(req->outbuf),0,5);
1510         SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1511
1512         /* The replies here are never long name. */
1513         SSVAL(req->outbuf, smb_flg2,
1514               SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1515         if (!allow_long_path_components) {
1516                 SSVAL(req->outbuf, smb_flg2,
1517                       SVAL(req->outbuf, smb_flg2)
1518                       & (~FLAGS2_LONG_PATH_COMPONENTS));
1519         }
1520
1521         /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1522         SSVAL(req->outbuf, smb_flg2,
1523               (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1524
1525         if (!directory) {
1526                 directory = dptr_path(dptr_num);
1527         }
1528
1529         DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1530                 smb_fn_name(CVAL(req->inbuf,smb_com)),
1531                 mask,
1532                 directory ? directory : "./",
1533                 dirtype,
1534                 numentries,
1535                 maxentries ));
1536
1537         END_PROFILE(SMBsearch);
1538         return;
1539 }
1540
1541 /****************************************************************************
1542  Reply to a fclose (stop directory search).
1543 ****************************************************************************/
1544
1545 void reply_fclose(struct smb_request *req)
1546 {
1547         int status_len;
1548         char status[21];
1549         int dptr_num= -2;
1550         char *p;
1551         char *path = NULL;
1552         NTSTATUS err;
1553         bool path_contains_wcard = False;
1554         TALLOC_CTX *ctx = talloc_tos();
1555
1556         START_PROFILE(SMBfclose);
1557
1558         if (lp_posix_pathnames()) {
1559                 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1560                 END_PROFILE(SMBfclose);
1561                 return;
1562         }
1563
1564         p = smb_buf(req->inbuf) + 1;
1565         p += srvstr_get_path_wcard(ctx,
1566                                 (char *)req->inbuf,
1567                                 req->flags2,
1568                                 &path,
1569                                 p,
1570                                 0,
1571                                 STR_TERMINATE,
1572                                 &err,
1573                                 &path_contains_wcard);
1574         if (!NT_STATUS_IS_OK(err)) {
1575                 reply_nterror(req, err);
1576                 END_PROFILE(SMBfclose);
1577                 return;
1578         }
1579         p++;
1580         status_len = SVAL(p,0);
1581         p += 2;
1582
1583         if (status_len == 0) {
1584                 reply_doserror(req, ERRSRV, ERRsrverror);
1585                 END_PROFILE(SMBfclose);
1586                 return;
1587         }
1588
1589         memcpy(status,p,21);
1590
1591         if(dptr_fetch(status+12,&dptr_num)) {
1592                 /*  Close the dptr - we know it's gone */
1593                 dptr_close(&dptr_num);
1594         }
1595
1596         reply_outbuf(req, 1, 0);
1597         SSVAL(req->outbuf,smb_vwv0,0);
1598
1599         DEBUG(3,("search close\n"));
1600
1601         END_PROFILE(SMBfclose);
1602         return;
1603 }
1604
1605 /****************************************************************************
1606  Reply to an open.
1607 ****************************************************************************/
1608
1609 void reply_open(struct smb_request *req)
1610 {
1611         connection_struct *conn = req->conn;
1612         char *fname = NULL;
1613         uint32 fattr=0;
1614         SMB_OFF_T size = 0;
1615         time_t mtime=0;
1616         int info;
1617         SMB_STRUCT_STAT sbuf;
1618         files_struct *fsp;
1619         int oplock_request;
1620         int deny_mode;
1621         uint32 dos_attr;
1622         uint32 access_mask;
1623         uint32 share_mode;
1624         uint32 create_disposition;
1625         uint32 create_options = 0;
1626         NTSTATUS status;
1627         TALLOC_CTX *ctx = talloc_tos();
1628
1629         START_PROFILE(SMBopen);
1630
1631         if (req->wct < 2) {
1632                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1633                 END_PROFILE(SMBopen);
1634                 return;
1635         }
1636
1637         oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1638         deny_mode = SVAL(req->inbuf,smb_vwv0);
1639         dos_attr = SVAL(req->inbuf,smb_vwv1);
1640
1641         srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1642                         smb_buf(req->inbuf)+1, 0,
1643                         STR_TERMINATE, &status);
1644         if (!NT_STATUS_IS_OK(status)) {
1645                 reply_nterror(req, status);
1646                 END_PROFILE(SMBopen);
1647                 return;
1648         }
1649
1650         if (!map_open_params_to_ntcreate(
1651                     fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
1652                     &share_mode, &create_disposition, &create_options)) {
1653                 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1654                 END_PROFILE(SMBopen);
1655                 return;
1656         }
1657
1658         status = create_file(conn,                      /* conn */
1659                              req,                       /* req */
1660                              0,                         /* root_dir_fid */
1661                              fname,                     /* fname */
1662                              access_mask,               /* access_mask */
1663                              share_mode,                /* share_access */
1664                              create_disposition,        /* create_disposition*/
1665                              create_options,            /* create_options */
1666                              dos_attr,                  /* file_attributes */
1667                              oplock_request,            /* oplock_request */
1668                              0,                         /* allocation_size */
1669                              NULL,                      /* sd */
1670                              NULL,                      /* ea_list */
1671                              &fsp,                      /* result */
1672                              &info,                     /* pinfo */
1673                              &sbuf);                    /* psbuf */
1674
1675         if (!NT_STATUS_IS_OK(status)) {
1676                 if (open_was_deferred(req->mid)) {
1677                         /* We have re-scheduled this call. */
1678                         END_PROFILE(SMBopen);
1679                         return;
1680                 }
1681                 reply_openerror(req, status);
1682                 END_PROFILE(SMBopen);
1683                 return;
1684         }
1685
1686         size = sbuf.st_size;
1687         fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1688         mtime = sbuf.st_mtime;
1689
1690         if (fattr & aDIR) {
1691                 DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
1692                 close_file(fsp,ERROR_CLOSE);
1693                 reply_doserror(req, ERRDOS,ERRnoaccess);
1694                 END_PROFILE(SMBopen);
1695                 return;
1696         }
1697
1698         reply_outbuf(req, 7, 0);
1699         SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1700         SSVAL(req->outbuf,smb_vwv1,fattr);
1701         if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1702                 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1703         } else {
1704                 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1705         }
1706         SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1707         SSVAL(req->outbuf,smb_vwv6,deny_mode);
1708
1709         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1710                 SCVAL(req->outbuf,smb_flg,
1711                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1712         }
1713     
1714         if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1715                 SCVAL(req->outbuf,smb_flg,
1716                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1717         }
1718         END_PROFILE(SMBopen);
1719         return;
1720 }
1721
1722 /****************************************************************************
1723  Reply to an open and X.
1724 ****************************************************************************/
1725
1726 void reply_open_and_X(struct smb_request *req)
1727 {
1728         connection_struct *conn = req->conn;
1729         char *fname = NULL;
1730         uint16 open_flags;
1731         int deny_mode;
1732         uint32 smb_attr;
1733         /* Breakout the oplock request bits so we can set the
1734                 reply bits separately. */
1735         int ex_oplock_request;
1736         int core_oplock_request;
1737         int oplock_request;
1738 #if 0
1739         int smb_sattr = SVAL(req->inbuf,smb_vwv4);
1740         uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6);
1741 #endif
1742         int smb_ofun;
1743         uint32 fattr=0;
1744         int mtime=0;
1745         SMB_STRUCT_STAT sbuf;
1746         int smb_action = 0;
1747         files_struct *fsp;
1748         NTSTATUS status;
1749         SMB_BIG_UINT allocation_size;
1750         ssize_t retval = -1;
1751         uint32 access_mask;
1752         uint32 share_mode;
1753         uint32 create_disposition;
1754         uint32 create_options = 0;
1755         TALLOC_CTX *ctx = talloc_tos();
1756
1757         START_PROFILE(SMBopenX);
1758
1759         if (req->wct < 15) {
1760                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1761                 END_PROFILE(SMBopenX);
1762                 return;
1763         }
1764
1765         open_flags = SVAL(req->inbuf,smb_vwv2);
1766         deny_mode = SVAL(req->inbuf,smb_vwv3);
1767         smb_attr = SVAL(req->inbuf,smb_vwv5);
1768         ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1769         core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1770         oplock_request = ex_oplock_request | core_oplock_request;
1771         smb_ofun = SVAL(req->inbuf,smb_vwv8);
1772         allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv9);
1773
1774         /* If it's an IPC, pass off the pipe handler. */
1775         if (IS_IPC(conn)) {
1776                 if (lp_nt_pipe_support()) {
1777                         reply_open_pipe_and_X(conn, req);
1778                 } else {
1779                         reply_doserror(req, ERRSRV, ERRaccess);
1780                 }
1781                 END_PROFILE(SMBopenX);
1782                 return;
1783         }
1784
1785         /* XXXX we need to handle passed times, sattr and flags */
1786         srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1787                         smb_buf(req->inbuf), 0, STR_TERMINATE,
1788                         &status);
1789         if (!NT_STATUS_IS_OK(status)) {
1790                 reply_nterror(req, status);
1791                 END_PROFILE(SMBopenX);
1792                 return;
1793         }
1794
1795         if (!map_open_params_to_ntcreate(
1796                     fname, deny_mode, smb_ofun, &access_mask,
1797                     &share_mode, &create_disposition, &create_options)) {
1798                 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1799                 END_PROFILE(SMBopenX);
1800                 return;
1801         }
1802
1803         status = create_file(conn,                      /* conn */
1804                              req,                       /* req */
1805                              0,                         /* root_dir_fid */
1806                              fname,                     /* fname */
1807                              access_mask,               /* access_mask */
1808                              share_mode,                /* share_access */
1809                              create_disposition,        /* create_disposition*/
1810                              create_options,            /* create_options */
1811                              smb_attr,                  /* file_attributes */
1812                              oplock_request,            /* oplock_request */
1813                              0,                         /* allocation_size */
1814                              NULL,                      /* sd */
1815                              NULL,                      /* ea_list */
1816                              &fsp,                      /* result */
1817                              &smb_action,               /* pinfo */
1818                              &sbuf);                    /* psbuf */
1819
1820         if (!NT_STATUS_IS_OK(status)) {
1821                 END_PROFILE(SMBopenX);
1822                 if (open_was_deferred(req->mid)) {
1823                         /* We have re-scheduled this call. */
1824                         return;
1825                 }
1826                 reply_openerror(req, status);
1827                 return;
1828         }
1829
1830         /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1831            if the file is truncated or created. */
1832         if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1833                 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1834                 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1835                         close_file(fsp,ERROR_CLOSE);
1836                         reply_nterror(req, NT_STATUS_DISK_FULL);
1837                         END_PROFILE(SMBopenX);
1838                         return;
1839                 }
1840                 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1841                 if (retval < 0) {
1842                         close_file(fsp,ERROR_CLOSE);
1843                         reply_nterror(req, NT_STATUS_DISK_FULL);
1844                         END_PROFILE(SMBopenX);
1845                         return;
1846                 }
1847                 sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
1848         }
1849
1850         fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1851         mtime = sbuf.st_mtime;
1852         if (fattr & aDIR) {
1853                 close_file(fsp,ERROR_CLOSE);
1854                 reply_doserror(req, ERRDOS, ERRnoaccess);
1855                 END_PROFILE(SMBopenX);
1856                 return;
1857         }
1858
1859         /* If the caller set the extended oplock request bit
1860                 and we granted one (by whatever means) - set the
1861                 correct bit for extended oplock reply.
1862         */
1863
1864         if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1865                 smb_action |= EXTENDED_OPLOCK_GRANTED;
1866         }
1867
1868         if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1869                 smb_action |= EXTENDED_OPLOCK_GRANTED;
1870         }
1871
1872         /* If the caller set the core oplock request bit
1873                 and we granted one (by whatever means) - set the
1874                 correct bit for core oplock reply.
1875         */
1876
1877         if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1878                 reply_outbuf(req, 19, 0);
1879         } else {
1880                 reply_outbuf(req, 15, 0);
1881         }
1882
1883         if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1884                 SCVAL(req->outbuf, smb_flg,
1885                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1886         }
1887
1888         if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1889                 SCVAL(req->outbuf, smb_flg,
1890                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1891         }
1892
1893         SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
1894         SSVAL(req->outbuf,smb_vwv3,fattr);
1895         if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1896                 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
1897         } else {
1898                 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
1899         }
1900         SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size);
1901         SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
1902         SSVAL(req->outbuf,smb_vwv11,smb_action);
1903
1904         if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1905                 SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
1906         }
1907
1908         END_PROFILE(SMBopenX);
1909         chain_reply(req);
1910         return;
1911 }
1912
1913 /****************************************************************************
1914  Reply to a SMBulogoffX.
1915 ****************************************************************************/
1916
1917 void reply_ulogoffX(struct smb_request *req)
1918 {
1919         user_struct *vuser;
1920
1921         START_PROFILE(SMBulogoffX);
1922
1923         vuser = get_valid_user_struct(req->vuid);
1924
1925         if(vuser == NULL) {
1926                 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
1927                          req->vuid));
1928         }
1929
1930         /* in user level security we are supposed to close any files
1931                 open by this user */
1932         if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
1933                 file_close_user(req->vuid);
1934         }
1935
1936         invalidate_vuid(req->vuid);
1937
1938         reply_outbuf(req, 2, 0);
1939
1940         DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
1941
1942         END_PROFILE(SMBulogoffX);
1943         chain_reply(req);
1944 }
1945
1946 /****************************************************************************
1947  Reply to a mknew or a create.
1948 ****************************************************************************/
1949
1950 void reply_mknew(struct smb_request *req)
1951 {
1952         connection_struct *conn = req->conn;
1953         char *fname = NULL;
1954         int com;
1955         uint32 fattr = 0;
1956         struct timespec ts[2];
1957         files_struct *fsp;
1958         int oplock_request = 0;
1959         SMB_STRUCT_STAT sbuf;
1960         NTSTATUS status;
1961         uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
1962         uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1963         uint32 create_disposition;
1964         uint32 create_options = 0;
1965         TALLOC_CTX *ctx = talloc_tos();
1966
1967         START_PROFILE(SMBcreate);
1968
1969         if (req->wct < 3) {
1970                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1971                 END_PROFILE(SMBcreate);
1972                 return;
1973         }
1974
1975         fattr = SVAL(req->inbuf,smb_vwv0);
1976         oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1977         com = SVAL(req->inbuf,smb_com);
1978
1979         ts[1] =convert_time_t_to_timespec(
1980                         srv_make_unix_date3(req->inbuf + smb_vwv1));
1981                         /* mtime. */
1982
1983         srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1984                         smb_buf(req->inbuf) + 1, 0,
1985                         STR_TERMINATE, &status);
1986         if (!NT_STATUS_IS_OK(status)) {
1987                 reply_nterror(req, status);
1988                 END_PROFILE(SMBcreate);
1989                 return;
1990         }
1991
1992         if (fattr & aVOLID) {
1993                 DEBUG(0,("Attempt to create file (%s) with volid set - "
1994                         "please report this\n", fname));
1995         }
1996
1997         if(com == SMBmknew) {
1998                 /* We should fail if file exists. */
1999                 create_disposition = FILE_CREATE;
2000         } else {
2001                 /* Create if file doesn't exist, truncate if it does. */
2002                 create_disposition = FILE_OVERWRITE_IF;
2003         }
2004
2005         status = create_file(conn,                      /* conn */
2006                              req,                       /* req */
2007                              0,                         /* root_dir_fid */
2008                              fname,                     /* fname */
2009                              access_mask,               /* access_mask */
2010                              share_mode,                /* share_access */
2011                              create_disposition,        /* create_disposition*/
2012                              create_options,            /* create_options */
2013                              fattr,                     /* file_attributes */
2014                              oplock_request,            /* oplock_request */
2015                              0,                         /* allocation_size */
2016                              NULL,                      /* sd */
2017                              NULL,                      /* ea_list */
2018                              &fsp,                      /* result */
2019                              NULL,                      /* pinfo */
2020                              &sbuf);                    /* psbuf */
2021
2022         if (!NT_STATUS_IS_OK(status)) {
2023                 END_PROFILE(SMBcreate);
2024                 if (open_was_deferred(req->mid)) {
2025                         /* We have re-scheduled this call. */
2026                         return;
2027                 }
2028                 reply_openerror(req, status);
2029                 return;
2030         }
2031
2032         ts[0] = get_atimespec(&sbuf); /* atime. */
2033         status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true);
2034         if (!NT_STATUS_IS_OK(status)) {
2035                 END_PROFILE(SMBcreate);
2036                 reply_openerror(req, status);
2037                 return;
2038         }
2039
2040         reply_outbuf(req, 1, 0);
2041         SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2042
2043         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2044                 SCVAL(req->outbuf,smb_flg,
2045                                 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2046         }
2047
2048         if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2049                 SCVAL(req->outbuf,smb_flg,
2050                                 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2051         }
2052
2053         DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) );
2054         DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
2055                     fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
2056
2057         END_PROFILE(SMBcreate);
2058         return;
2059 }
2060
2061 /****************************************************************************
2062  Reply to a create temporary file.
2063 ****************************************************************************/
2064
2065 void reply_ctemp(struct smb_request *req)
2066 {
2067         connection_struct *conn = req->conn;
2068         char *fname = NULL;
2069         uint32 fattr;
2070         files_struct *fsp;
2071         int oplock_request;
2072         int tmpfd;
2073         SMB_STRUCT_STAT sbuf;
2074         char *s;
2075         NTSTATUS status;
2076         TALLOC_CTX *ctx = talloc_tos();
2077
2078         START_PROFILE(SMBctemp);
2079
2080         if (req->wct < 3) {
2081                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2082                 END_PROFILE(SMBctemp);
2083                 return;
2084         }
2085
2086         fattr = SVAL(req->inbuf,smb_vwv0);
2087         oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2088
2089         srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
2090                         smb_buf(req->inbuf)+1, 0, STR_TERMINATE,
2091                         &status);
2092         if (!NT_STATUS_IS_OK(status)) {
2093                 reply_nterror(req, status);
2094                 END_PROFILE(SMBctemp);
2095                 return;
2096         }
2097         if (*fname) {
2098                 fname = talloc_asprintf(ctx,
2099                                 "%s/TMXXXXXX",
2100                                 fname);
2101         } else {
2102                 fname = talloc_strdup(ctx, "TMXXXXXX");
2103         }
2104
2105         if (!fname) {
2106                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2107                 END_PROFILE(SMBctemp);
2108                 return;
2109         }
2110
2111         status = resolve_dfspath(ctx, conn,
2112                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
2113                                 fname,
2114                                 &fname);
2115         if (!NT_STATUS_IS_OK(status)) {
2116                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2117                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2118                                         ERRSRV, ERRbadpath);
2119                         END_PROFILE(SMBctemp);
2120                         return;
2121                 }
2122                 reply_nterror(req, status);
2123                 END_PROFILE(SMBctemp);
2124                 return;
2125         }
2126
2127         status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
2128         if (!NT_STATUS_IS_OK(status)) {
2129                 reply_nterror(req, status);
2130                 END_PROFILE(SMBctemp);
2131                 return;
2132         }
2133
2134         status = check_name(conn, fname);
2135         if (!NT_STATUS_IS_OK(status)) {
2136                 reply_nterror(req, status);
2137                 END_PROFILE(SMBctemp);
2138                 return;
2139         }
2140
2141         tmpfd = smb_mkstemp(fname);
2142         if (tmpfd == -1) {
2143                 reply_unixerror(req, ERRDOS, ERRnoaccess);
2144                 END_PROFILE(SMBctemp);
2145                 return;
2146         }
2147
2148         SMB_VFS_STAT(conn,fname,&sbuf);
2149
2150         /* We should fail if file does not exist. */
2151         status = open_file_ntcreate(conn, req, fname, &sbuf,
2152                                 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
2153                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2154                                 FILE_OPEN,
2155                                 0,
2156                                 fattr,
2157                                 oplock_request,
2158                                 NULL, &fsp);
2159
2160         /* close fd from smb_mkstemp() */
2161         close(tmpfd);
2162
2163         if (!NT_STATUS_IS_OK(status)) {
2164                 if (open_was_deferred(req->mid)) {
2165                         /* We have re-scheduled this call. */
2166                         END_PROFILE(SMBctemp);
2167                         return;
2168                 }
2169                 reply_openerror(req, status);
2170                 END_PROFILE(SMBctemp);
2171                 return;
2172         }
2173
2174         reply_outbuf(req, 1, 0);
2175         SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2176
2177         /* the returned filename is relative to the directory */
2178         s = strrchr_m(fsp->fsp_name, '/');
2179         if (!s) {
2180                 s = fsp->fsp_name;
2181         } else {
2182                 s++;
2183         }
2184
2185 #if 0
2186         /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2187            thing in the byte section. JRA */
2188         SSVALS(p, 0, -1); /* what is this? not in spec */
2189 #endif
2190         if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2191             == -1) {
2192                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2193                 END_PROFILE(SMBctemp);
2194                 return;
2195         }
2196
2197         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2198                 SCVAL(req->outbuf, smb_flg,
2199                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2200         }
2201   
2202         if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2203                 SCVAL(req->outbuf, smb_flg,
2204                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2205         }
2206
2207         DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
2208         DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
2209                     fsp->fh->fd, (unsigned int)sbuf.st_mode ) );
2210
2211         END_PROFILE(SMBctemp);
2212         return;
2213 }
2214
2215 /*******************************************************************
2216  Check if a user is allowed to rename a file.
2217 ********************************************************************/
2218
2219 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2220                            uint16 dirtype, SMB_STRUCT_STAT *pst)
2221 {
2222         uint32 fmode;
2223
2224         if (!CAN_WRITE(conn)) {
2225                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2226         }
2227
2228         fmode = dos_mode(conn, fsp->fsp_name, pst);
2229         if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
2230                 return NT_STATUS_NO_SUCH_FILE;
2231         }
2232
2233         if (S_ISDIR(pst->st_mode)) {
2234                 return NT_STATUS_OK;
2235         }
2236
2237         if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
2238                 return NT_STATUS_OK;
2239         }
2240
2241         return NT_STATUS_ACCESS_DENIED;
2242 }
2243
2244 /*******************************************************************
2245  * unlink a file with all relevant access checks
2246  *******************************************************************/
2247
2248 static NTSTATUS do_unlink(connection_struct *conn,
2249                         struct smb_request *req,
2250                         const char *fname,
2251                         uint32 dirtype)
2252 {
2253         SMB_STRUCT_STAT sbuf;
2254         uint32 fattr;
2255         files_struct *fsp;
2256         uint32 dirtype_orig = dirtype;
2257         NTSTATUS status;
2258
2259         DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
2260
2261         if (!CAN_WRITE(conn)) {
2262                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2263         }
2264
2265         if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
2266                 return map_nt_error_from_unix(errno);
2267         }
2268
2269         fattr = dos_mode(conn,fname,&sbuf);
2270
2271         if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2272                 dirtype = aDIR|aARCH|aRONLY;
2273         }
2274
2275         dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
2276         if (!dirtype) {
2277                 return NT_STATUS_NO_SUCH_FILE;
2278         }
2279
2280         if (!dir_check_ftype(conn, fattr, dirtype)) {
2281                 if (fattr & aDIR) {
2282                         return NT_STATUS_FILE_IS_A_DIRECTORY;
2283                 }
2284                 return NT_STATUS_NO_SUCH_FILE;
2285         }
2286
2287         if (dirtype_orig & 0x8000) {
2288                 /* These will never be set for POSIX. */
2289                 return NT_STATUS_NO_SUCH_FILE;
2290         }
2291
2292 #if 0
2293         if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2294                 return NT_STATUS_FILE_IS_A_DIRECTORY;
2295         }
2296
2297         if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2298                 return NT_STATUS_NO_SUCH_FILE;
2299         }
2300
2301         if (dirtype & 0xFF00) {
2302                 /* These will never be set for POSIX. */
2303                 return NT_STATUS_NO_SUCH_FILE;
2304         }
2305
2306         dirtype &= 0xFF;
2307         if (!dirtype) {
2308                 return NT_STATUS_NO_SUCH_FILE;
2309         }
2310
2311         /* Can't delete a directory. */
2312         if (fattr & aDIR) {
2313                 return NT_STATUS_FILE_IS_A_DIRECTORY;
2314         }
2315 #endif
2316
2317 #if 0 /* JRATEST */
2318         else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
2319                 return NT_STATUS_OBJECT_NAME_INVALID;
2320 #endif /* JRATEST */
2321
2322         /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
2323
2324           On a Windows share, a file with read-only dosmode can be opened with
2325           DELETE_ACCESS. But on a Samba share (delete readonly = no), it
2326           fails with NT_STATUS_CANNOT_DELETE error.
2327
2328           This semantic causes a problem that a user can not
2329           rename a file with read-only dosmode on a Samba share
2330           from a Windows command prompt (i.e. cmd.exe, but can rename
2331           from Windows Explorer).
2332         */
2333
2334         if (!lp_delete_readonly(SNUM(conn))) {
2335                 if (fattr & aRONLY) {
2336                         return NT_STATUS_CANNOT_DELETE;
2337                 }
2338         }
2339
2340         /* On open checks the open itself will check the share mode, so
2341            don't do it here as we'll get it wrong. */
2342
2343         status = create_file_unixpath
2344                 (conn,                  /* conn */
2345                  req,                   /* req */
2346                  fname,                 /* fname */
2347                  DELETE_ACCESS,         /* access_mask */
2348                  FILE_SHARE_NONE,       /* share_access */
2349                  FILE_OPEN,             /* create_disposition*/
2350                  FILE_NON_DIRECTORY_FILE, /* create_options */
2351                  FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2352                  0,                     /* oplock_request */
2353                  0,                     /* allocation_size */
2354                  NULL,                  /* sd */
2355                  NULL,                  /* ea_list */
2356                  &fsp,                  /* result */
2357                  NULL,                  /* pinfo */
2358                  &sbuf);                /* psbuf */
2359
2360         if (!NT_STATUS_IS_OK(status)) {
2361                 DEBUG(10, ("create_file_unixpath failed: %s\n",
2362                            nt_errstr(status)));
2363                 return status;
2364         }
2365
2366         /* The set is across all open files on this dev/inode pair. */
2367         if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) {
2368                 close_file(fsp, NORMAL_CLOSE);
2369                 return NT_STATUS_ACCESS_DENIED;
2370         }
2371
2372         return close_file(fsp,NORMAL_CLOSE);
2373 }
2374
2375 /****************************************************************************
2376  The guts of the unlink command, split out so it may be called by the NT SMB
2377  code.
2378 ****************************************************************************/
2379
2380 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2381                           uint32 dirtype, const char *name_in, bool has_wild)
2382 {
2383         const char *directory = NULL;
2384         char *mask = NULL;
2385         char *name = NULL;
2386         char *p = NULL;
2387         int count=0;
2388         NTSTATUS status = NT_STATUS_OK;
2389         SMB_STRUCT_STAT sbuf;
2390         TALLOC_CTX *ctx = talloc_tos();
2391
2392         status = unix_convert(ctx, conn, name_in, has_wild, &name, NULL, &sbuf);
2393         if (!NT_STATUS_IS_OK(status)) {
2394                 return status;
2395         }
2396
2397         p = strrchr_m(name,'/');
2398         if (!p) {
2399                 directory = talloc_strdup(ctx, ".");
2400                 if (!directory) {
2401                         return NT_STATUS_NO_MEMORY;
2402                 }
2403                 mask = name;
2404         } else {
2405                 *p = 0;
2406                 directory = name;
2407                 mask = p+1;
2408         }
2409
2410         /*
2411          * We should only check the mangled cache
2412          * here if unix_convert failed. This means
2413          * that the path in 'mask' doesn't exist
2414          * on the file system and so we need to look
2415          * for a possible mangle. This patch from
2416          * Tine Smukavec <valentin.smukavec@hermes.si>.
2417          */
2418
2419         if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) {
2420                 char *new_mask = NULL;
2421                 mangle_lookup_name_from_8_3(ctx,
2422                                 mask,
2423                                 &new_mask,
2424                                 conn->params );
2425                 if (new_mask) {
2426                         mask = new_mask;
2427                 }
2428         }
2429
2430         if (!has_wild) {
2431                 directory = talloc_asprintf(ctx,
2432                                 "%s/%s",
2433                                 directory,
2434                                 mask);
2435                 if (!directory) {
2436                         return NT_STATUS_NO_MEMORY;
2437                 }
2438                 if (dirtype == 0) {
2439                         dirtype = FILE_ATTRIBUTE_NORMAL;
2440                 }
2441
2442                 status = check_name(conn, directory);
2443                 if (!NT_STATUS_IS_OK(status)) {
2444                         return status;
2445                 }
2446
2447                 status = do_unlink(conn, req, directory, dirtype);
2448                 if (!NT_STATUS_IS_OK(status)) {
2449                         return status;
2450                 }
2451
2452                 count++;
2453         } else {
2454                 struct smb_Dir *dir_hnd = NULL;
2455                 long offset = 0;
2456                 const char *dname;
2457
2458                 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2459                         return NT_STATUS_OBJECT_NAME_INVALID;
2460                 }
2461
2462                 if (strequal(mask,"????????.???")) {
2463                         mask[0] = '*';
2464                         mask[1] = '\0';
2465                 }
2466
2467                 status = check_name(conn, directory);
2468                 if (!NT_STATUS_IS_OK(status)) {
2469                         return status;
2470                 }
2471
2472                 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask,
2473                                   dirtype);
2474                 if (dir_hnd == NULL) {
2475                         return map_nt_error_from_unix(errno);
2476                 }
2477
2478                 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2479                    the pattern matches against the long name, otherwise the short name 
2480                    We don't implement this yet XXXX
2481                 */
2482
2483                 status = NT_STATUS_NO_SUCH_FILE;
2484
2485                 while ((dname = ReadDirName(dir_hnd, &offset))) {
2486                         SMB_STRUCT_STAT st;
2487                         char *fname = NULL;
2488
2489                         if (!is_visible_file(conn, directory, dname, &st, True)) {
2490                                 continue;
2491                         }
2492
2493                         /* Quick check for "." and ".." */
2494                         if (ISDOT(dname) || ISDOTDOT(dname)) {
2495                                 continue;
2496                         }
2497
2498                         if(!mask_match(dname, mask, conn->case_sensitive)) {
2499                                 continue;
2500                         }
2501
2502                         fname = talloc_asprintf(ctx, "%s/%s",
2503                                         directory,
2504                                         dname);
2505                         if (!fname) {
2506                                 return NT_STATUS_NO_MEMORY;
2507                         }
2508
2509                         status = check_name(conn, fname);
2510                         if (!NT_STATUS_IS_OK(status)) {
2511                                 TALLOC_FREE(dir_hnd);
2512                                 return status;
2513                         }
2514
2515                         status = do_unlink(conn, req, fname, dirtype);
2516                         if (!NT_STATUS_IS_OK(status)) {
2517                                 TALLOC_FREE(fname);
2518                                 continue;
2519                         }
2520
2521                         count++;
2522                         DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2523                                  fname));
2524
2525                         TALLOC_FREE(fname);
2526                 }
2527                 TALLOC_FREE(dir_hnd);
2528         }
2529
2530         if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
2531                 status = map_nt_error_from_unix(errno);
2532         }
2533
2534         return status;
2535 }
2536
2537 /****************************************************************************
2538  Reply to a unlink
2539 ****************************************************************************/
2540
2541 void reply_unlink(struct smb_request *req)
2542 {
2543         connection_struct *conn = req->conn;
2544         char *name = NULL;
2545         uint32 dirtype;
2546         NTSTATUS status;
2547         bool path_contains_wcard = False;
2548         TALLOC_CTX *ctx = talloc_tos();
2549
2550         START_PROFILE(SMBunlink);
2551
2552         if (req->wct < 1) {
2553                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2554                 END_PROFILE(SMBunlink);
2555                 return;
2556         }
2557
2558         dirtype = SVAL(req->inbuf,smb_vwv0);
2559
2560         srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
2561                               smb_buf(req->inbuf) + 1, 0,
2562                               STR_TERMINATE, &status, &path_contains_wcard);
2563         if (!NT_STATUS_IS_OK(status)) {
2564                 reply_nterror(req, status);
2565                 END_PROFILE(SMBunlink);
2566                 return;
2567         }
2568
2569         status = resolve_dfspath_wcard(ctx, conn,
2570                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
2571                                        name,
2572                                        &name,
2573                                        &path_contains_wcard);
2574         if (!NT_STATUS_IS_OK(status)) {
2575                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2576                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2577                                         ERRSRV, ERRbadpath);
2578                         END_PROFILE(SMBunlink);
2579                         return;
2580                 }
2581                 reply_nterror(req, status);
2582                 END_PROFILE(SMBunlink);
2583                 return;
2584         }
2585
2586         DEBUG(3,("reply_unlink : %s\n",name));
2587
2588         status = unlink_internals(conn, req, dirtype, name,
2589                                   path_contains_wcard);
2590         if (!NT_STATUS_IS_OK(status)) {
2591                 if (open_was_deferred(req->mid)) {
2592                         /* We have re-scheduled this call. */
2593                         END_PROFILE(SMBunlink);
2594                         return;
2595                 }
2596                 reply_nterror(req, status);
2597                 END_PROFILE(SMBunlink);
2598                 return;
2599         }
2600
2601         reply_outbuf(req, 0, 0);
2602         END_PROFILE(SMBunlink);
2603
2604         return;
2605 }
2606
2607 /****************************************************************************
2608  Fail for readbraw.
2609 ****************************************************************************/
2610
2611 static void fail_readraw(void)
2612 {
2613         const char *errstr = talloc_asprintf(talloc_tos(),
2614                         "FAIL ! reply_readbraw: socket write fail (%s)",
2615                         strerror(errno));
2616         if (!errstr) {
2617                 errstr = "";
2618         }
2619         exit_server_cleanly(errstr);
2620 }
2621
2622 /****************************************************************************
2623  Fake (read/write) sendfile. Returns -1 on read or write fail.
2624 ****************************************************************************/
2625
2626 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
2627                              size_t nread)
2628 {
2629         size_t bufsize;
2630         size_t tosend = nread;
2631         char *buf;
2632
2633         if (nread == 0) {
2634                 return 0;
2635         }
2636
2637         bufsize = MIN(nread, 65536);
2638
2639         if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2640                 return -1;
2641         }
2642
2643         while (tosend > 0) {
2644                 ssize_t ret;
2645                 size_t cur_read;
2646
2647                 if (tosend > bufsize) {
2648                         cur_read = bufsize;
2649                 } else {
2650                         cur_read = tosend;
2651                 }
2652                 ret = read_file(fsp,buf,startpos,cur_read);
2653                 if (ret == -1) {
2654                         SAFE_FREE(buf);
2655                         return -1;
2656                 }
2657
2658                 /* If we had a short read, fill with zeros. */
2659                 if (ret < cur_read) {
2660                         memset(buf, '\0', cur_read - ret);
2661                 }
2662
2663                 if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
2664                         SAFE_FREE(buf);
2665                         return -1;
2666                 }
2667                 tosend -= cur_read;
2668                 startpos += cur_read;
2669         }
2670
2671         SAFE_FREE(buf);
2672         return (ssize_t)nread;
2673 }
2674
2675 /****************************************************************************
2676  Return a readbraw error (4 bytes of zero).
2677 ****************************************************************************/
2678
2679 static void reply_readbraw_error(void)
2680 {
2681         char header[4];
2682         SIVAL(header,0,0);
2683         if (write_data(smbd_server_fd(),header,4) != 4) {
2684                 fail_readraw();
2685         }
2686 }
2687
2688 /****************************************************************************
2689  Use sendfile in readbraw.
2690 ****************************************************************************/
2691
2692 void send_file_readbraw(connection_struct *conn,
2693                         files_struct *fsp,
2694                         SMB_OFF_T startpos,
2695                         size_t nread,
2696                         ssize_t mincount)
2697 {
2698         char *outbuf = NULL;
2699         ssize_t ret=0;
2700
2701 #if defined(WITH_SENDFILE)
2702         /*
2703          * We can only use sendfile on a non-chained packet 
2704          * but we can use on a non-oplocked file. tridge proved this
2705          * on a train in Germany :-). JRA.
2706          * reply_readbraw has already checked the length.
2707          */
2708
2709         if ( (chain_size == 0) && (nread > 0) && (fsp->base_fsp == NULL) &&
2710             (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
2711                 char header[4];
2712                 DATA_BLOB header_blob;
2713
2714                 _smb_setlen(header,nread);
2715                 header_blob = data_blob_const(header, 4);
2716
2717                 if (SMB_VFS_SENDFILE(smbd_server_fd(), fsp,
2718                                 &header_blob, startpos, nread) == -1) {
2719                         /* Returning ENOSYS means no data at all was sent.
2720                          * Do this as a normal read. */
2721                         if (errno == ENOSYS) {
2722                                 goto normal_readbraw;
2723                         }
2724
2725                         /*
2726                          * Special hack for broken Linux with no working sendfile. If we
2727                          * return EINTR we sent the header but not the rest of the data.
2728                          * Fake this up by doing read/write calls.
2729                          */
2730                         if (errno == EINTR) {
2731                                 /* Ensure we don't do this again. */
2732                                 set_use_sendfile(SNUM(conn), False);
2733                                 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2734
2735                                 if (fake_sendfile(fsp, startpos, nread) == -1) {
2736                                         DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2737                                                 fsp->fsp_name, strerror(errno) ));
2738                                         exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2739                                 }
2740                                 return;
2741                         }
2742
2743                         DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2744                                 fsp->fsp_name, strerror(errno) ));
2745                         exit_server_cleanly("send_file_readbraw sendfile failed");
2746                 }
2747
2748                 return;
2749         }
2750 #endif
2751
2752 normal_readbraw:
2753
2754         outbuf = TALLOC_ARRAY(NULL, char, nread+4);
2755         if (!outbuf) {
2756                 DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
2757                         (unsigned)(nread+4)));
2758                 reply_readbraw_error();
2759                 return;
2760         }
2761
2762         if (nread > 0) {
2763                 ret = read_file(fsp,outbuf+4,startpos,nread);
2764 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2765                 if (ret < mincount)
2766                         ret = 0;
2767 #else
2768                 if (ret < nread)
2769                         ret = 0;
2770 #endif
2771         }
2772
2773         _smb_setlen(outbuf,ret);
2774         if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2775                 fail_readraw();
2776
2777         TALLOC_FREE(outbuf);
2778 }
2779
2780 /****************************************************************************
2781  Reply to a readbraw (core+ protocol).
2782 ****************************************************************************/
2783
2784 void reply_readbraw(struct smb_request *req)
2785 {
2786         connection_struct *conn = req->conn;
2787         ssize_t maxcount,mincount;
2788         size_t nread = 0;
2789         SMB_OFF_T startpos;
2790         files_struct *fsp;
2791         SMB_STRUCT_STAT st;
2792         SMB_OFF_T size = 0;
2793
2794         START_PROFILE(SMBreadbraw);
2795
2796         if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
2797                 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
2798                         "raw reads/writes are disallowed.");
2799         }
2800
2801         if (req->wct < 8) {
2802                 reply_readbraw_error();
2803                 END_PROFILE(SMBreadbraw);
2804                 return;
2805         }
2806
2807         /*
2808          * Special check if an oplock break has been issued
2809          * and the readraw request croses on the wire, we must
2810          * return a zero length response here.
2811          */
2812
2813         fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
2814
2815         /*
2816          * We have to do a check_fsp by hand here, as
2817          * we must always return 4 zero bytes on error,
2818          * not a NTSTATUS.
2819          */
2820
2821         if (!fsp || !conn || conn != fsp->conn ||
2822                         req->vuid != fsp->vuid ||
2823                         fsp->is_directory || fsp->fh->fd == -1) {
2824                 /*
2825                  * fsp could be NULL here so use the value from the packet. JRA.
2826                  */
2827                 DEBUG(3,("reply_readbraw: fnum %d not valid "
2828                         "- cache prime?\n",
2829                         (int)SVAL(req->inbuf,smb_vwv0)));
2830                 reply_readbraw_error();
2831                 END_PROFILE(SMBreadbraw);
2832                 return;
2833         }
2834
2835         /* Do a "by hand" version of CHECK_READ. */
2836         if (!(fsp->can_read ||
2837                         ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
2838                                 (fsp->access_mask & FILE_EXECUTE)))) {
2839                 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
2840                                 (int)SVAL(req->inbuf,smb_vwv0)));
2841                 reply_readbraw_error();
2842                 END_PROFILE(SMBreadbraw);
2843                 return;
2844         }
2845
2846         flush_write_cache(fsp, READRAW_FLUSH);
2847
2848         startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
2849         if(req->wct == 10) {
2850                 /*
2851                  * This is a large offset (64 bit) read.
2852                  */
2853 #ifdef LARGE_SMB_OFF_T
2854
2855                 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
2856
2857 #else /* !LARGE_SMB_OFF_T */
2858
2859                 /*
2860                  * Ensure we haven't been sent a >32 bit offset.
2861                  */
2862
2863                 if(IVAL(req->inbuf,smb_vwv8) != 0) {
2864                         DEBUG(0,("reply_readbraw: large offset "
2865                                 "(%x << 32) used and we don't support "
2866                                 "64 bit offsets.\n",
2867                         (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
2868                         reply_readbraw_error();
2869                         END_PROFILE(SMBreadbraw);
2870                         return;
2871                 }
2872
2873 #endif /* LARGE_SMB_OFF_T */
2874
2875                 if(startpos < 0) {
2876                         DEBUG(0,("reply_readbraw: negative 64 bit "
2877                                 "readraw offset (%.0f) !\n",
2878                                 (double)startpos ));
2879                         reply_readbraw_error();
2880                         END_PROFILE(SMBreadbraw);
2881                         return;
2882                 }      
2883         }
2884
2885         maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
2886         mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
2887
2888         /* ensure we don't overrun the packet size */
2889         maxcount = MIN(65535,maxcount);
2890
2891         if (is_locked(fsp,(uint32)req->smbpid,
2892                         (SMB_BIG_UINT)maxcount,
2893                         (SMB_BIG_UINT)startpos,
2894                         READ_LOCK)) {
2895                 reply_readbraw_error();
2896                 END_PROFILE(SMBreadbraw);
2897                 return;
2898         }
2899
2900         if (SMB_VFS_FSTAT(fsp, &st) == 0) {
2901                 size = st.st_size;
2902         }
2903
2904         if (startpos >= size) {
2905                 nread = 0;
2906         } else {
2907                 nread = MIN(maxcount,(size - startpos));
2908         }
2909
2910 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2911         if (nread < mincount)
2912                 nread = 0;
2913 #endif
2914   
2915         DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
2916                 "min=%lu nread=%lu\n",
2917                 fsp->fnum, (double)startpos,
2918                 (unsigned long)maxcount,
2919                 (unsigned long)mincount,
2920                 (unsigned long)nread ) );
2921   
2922         send_file_readbraw(conn, fsp, startpos, nread, mincount);
2923
2924         DEBUG(5,("reply_readbraw finished\n"));
2925         END_PROFILE(SMBreadbraw);
2926 }
2927
2928 #undef DBGC_CLASS
2929 #define DBGC_CLASS DBGC_LOCKING
2930
2931 /****************************************************************************
2932  Reply to a lockread (core+ protocol).
2933 ****************************************************************************/
2934
2935 void reply_lockread(struct smb_request *req)
2936 {
2937         connection_struct *conn = req->conn;
2938         ssize_t nread = -1;
2939         char *data;
2940         SMB_OFF_T startpos;
2941         size_t numtoread;
2942         NTSTATUS status;
2943         files_struct *fsp;
2944         struct byte_range_lock *br_lck = NULL;
2945         char *p = NULL;
2946
2947         START_PROFILE(SMBlockread);
2948
2949         if (req->wct < 5) {
2950                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2951                 END_PROFILE(SMBlockread);
2952                 return;
2953         }
2954
2955         fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
2956
2957         if (!check_fsp(conn, req, fsp)) {
2958                 END_PROFILE(SMBlockread);
2959                 return;
2960         }
2961
2962         if (!CHECK_READ(fsp,req->inbuf)) {
2963                 reply_doserror(req, ERRDOS, ERRbadaccess);
2964                 END_PROFILE(SMBlockread);
2965                 return;
2966         }
2967
2968         release_level_2_oplocks_on_change(fsp);
2969
2970         numtoread = SVAL(req->inbuf,smb_vwv1);
2971         startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
2972
2973         numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
2974
2975         reply_outbuf(req, 5, numtoread + 3);
2976
2977         data = smb_buf(req->outbuf) + 3;
2978         
2979         /*
2980          * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2981          * protocol request that predates the read/write lock concept. 
2982          * Thus instead of asking for a read lock here we need to ask
2983          * for a write lock. JRA.
2984          * Note that the requested lock size is unaffected by max_recv.
2985          */
2986         
2987         br_lck = do_lock(smbd_messaging_context(),
2988                         fsp,
2989                         req->smbpid,
2990                         (SMB_BIG_UINT)numtoread,
2991                         (SMB_BIG_UINT)startpos,
2992                         WRITE_LOCK,
2993                         WINDOWS_LOCK,
2994                         False, /* Non-blocking lock. */
2995                         &status,
2996                         NULL);
2997         TALLOC_FREE(br_lck);
2998
2999         if (NT_STATUS_V(status)) {
3000                 reply_nterror(req, status);
3001                 END_PROFILE(SMBlockread);
3002                 return;
3003         }
3004
3005         /*
3006          * However the requested READ size IS affected by max_recv. Insanity.... JRA.
3007          */
3008
3009         if (numtoread > max_recv) {
3010                 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
3011 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3012                         (unsigned int)numtoread, (unsigned int)max_recv ));
3013                 numtoread = MIN(numtoread,max_recv);
3014         }
3015         nread = read_file(fsp,data,startpos,numtoread);
3016
3017         if (nread < 0) {
3018                 reply_unixerror(req, ERRDOS, ERRnoaccess);
3019                 END_PROFILE(SMBlockread);
3020                 return;
3021         }
3022         
3023         srv_set_message((char *)req->outbuf, 5, nread+3, False);
3024
3025         SSVAL(req->outbuf,smb_vwv0,nread);
3026         SSVAL(req->outbuf,smb_vwv5,nread+3);
3027         p = smb_buf(req->outbuf);
3028         SCVAL(p,0,0); /* pad byte. */
3029         SSVAL(p,1,nread);
3030         
3031         DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
3032                  fsp->fnum, (int)numtoread, (int)nread));
3033
3034         END_PROFILE(SMBlockread);
3035         return;
3036 }
3037
3038 #undef DBGC_CLASS
3039 #define DBGC_CLASS DBGC_ALL
3040
3041 /****************************************************************************
3042  Reply to a read.
3043 ****************************************************************************/
3044
3045 void reply_read(struct smb_request *req)
3046 {
3047         connection_struct *conn = req->conn;
3048         size_t numtoread;
3049         ssize_t nread = 0;
3050         char *data;
3051         SMB_OFF_T startpos;
3052         int outsize = 0;
3053         files_struct *fsp;
3054
3055         START_PROFILE(SMBread);
3056
3057         if (req->wct < 3) {
3058                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3059                 END_PROFILE(SMBread);
3060                 return;
3061         }
3062
3063         fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3064
3065         if (!check_fsp(conn, req, fsp)) {
3066                 END_PROFILE(SMBread);
3067                 return;
3068         }
3069
3070         if (!CHECK_READ(fsp,req->inbuf)) {
3071                 reply_doserror(req, ERRDOS, ERRbadaccess);
3072                 END_PROFILE(SMBread);
3073                 return;
3074         }
3075
3076         numtoread = SVAL(req->inbuf,smb_vwv1);
3077         startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3078
3079         numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
3080
3081         /*
3082          * The requested read size cannot be greater than max_recv. JRA.
3083          */
3084         if (numtoread > max_recv) {
3085                 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
3086 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3087                         (unsigned int)numtoread, (unsigned int)max_recv ));
3088                 numtoread = MIN(numtoread,max_recv);
3089         }
3090
3091         reply_outbuf(req, 5, numtoread+3);
3092
3093         data = smb_buf(req->outbuf) + 3;
3094   
3095         if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtoread,
3096                       (SMB_BIG_UINT)startpos, READ_LOCK)) {
3097                 reply_doserror(req, ERRDOS,ERRlock);
3098                 END_PROFILE(SMBread);
3099                 return;
3100         }
3101
3102         if (numtoread > 0)
3103                 nread = read_file(fsp,data,startpos,numtoread);
3104
3105         if (nread < 0) {
3106                 reply_unixerror(req, ERRDOS,ERRnoaccess);
3107                 END_PROFILE(SMBread);
3108                 return;
3109         }
3110
3111         srv_set_message((char *)req->outbuf, 5, nread+3, False);
3112
3113         SSVAL(req->outbuf,smb_vwv0,nread);
3114         SSVAL(req->outbuf,smb_vwv5,nread+3);
3115         SCVAL(smb_buf(req->outbuf),0,1);
3116         SSVAL(smb_buf(req->outbuf),1,nread);
3117   
3118         DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
3119                 fsp->fnum, (int)numtoread, (int)nread ) );
3120
3121         END_PROFILE(SMBread);
3122         return;
3123 }
3124
3125 /****************************************************************************
3126  Setup readX header.
3127 ****************************************************************************/
3128
3129 static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
3130 {
3131         int outsize;
3132         char *data;
3133
3134         outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
3135         data = smb_buf(outbuf);
3136
3137         memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
3138
3139         SCVAL(outbuf,smb_vwv0,0xFF);
3140         SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
3141         SSVAL(outbuf,smb_vwv5,smb_maxcnt);
3142         SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
3143         SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
3144         SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
3145         /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
3146         _smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
3147         return outsize;
3148 }
3149
3150 /****************************************************************************
3151  Reply to a read and X - possibly using sendfile.
3152 ****************************************************************************/
3153
3154 static void send_file_readX(connection_struct *conn, struct smb_request *req,
3155                             files_struct *fsp, SMB_OFF_T startpos,
3156                             size_t smb_maxcnt)
3157 {
3158         SMB_STRUCT_STAT sbuf;
3159         ssize_t nread = -1;
3160
3161         if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
3162                 reply_unixerror(req, ERRDOS, ERRnoaccess);
3163                 return;
3164         }
3165
3166         if (startpos > sbuf.st_size) {
3167                 smb_maxcnt = 0;
3168         } else if (smb_maxcnt > (sbuf.st_size - startpos)) {
3169                 smb_maxcnt = (sbuf.st_size - startpos);
3170         }
3171
3172         if (smb_maxcnt == 0) {
3173                 goto normal_read;
3174         }
3175
3176 #if defined(WITH_SENDFILE)
3177         /*
3178          * We can only use sendfile on a non-chained packet
3179          * but we can use on a non-oplocked file. tridge proved this
3180          * on a train in Germany :-). JRA.
3181          */
3182
3183         if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
3184             !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
3185             lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
3186                 uint8 headerbuf[smb_size + 12 * 2];
3187                 DATA_BLOB header;
3188
3189                 /*
3190                  * Set up the packet header before send. We
3191                  * assume here the sendfile will work (get the
3192                  * correct amount of data).
3193                  */
3194
3195                 header = data_blob_const(headerbuf, sizeof(headerbuf));
3196
3197                 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3198                 setup_readX_header((char *)headerbuf, smb_maxcnt);
3199
3200                 if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
3201                         /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
3202                         if (errno == ENOSYS) {
3203                                 goto normal_read;
3204                         }
3205
3206                         /*
3207                          * Special hack for broken Linux with no working sendfile. If we
3208                          * return EINTR we sent the header but not the rest of the data.
3209                          * Fake this up by doing read/write calls.
3210                          */
3211
3212                         if (errno == EINTR) {
3213                                 /* Ensure we don't do this again. */
3214                                 set_use_sendfile(SNUM(conn), False);
3215                                 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
3216                                 nread = fake_sendfile(fsp, startpos,
3217                                                       smb_maxcnt);
3218                                 if (nread == -1) {
3219                                         DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3220                                                 fsp->fsp_name, strerror(errno) ));
3221                                         exit_server_cleanly("send_file_readX: fake_sendfile failed");
3222                                 }
3223                                 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
3224                                         fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3225                                 /* No outbuf here means successful sendfile. */
3226                                 TALLOC_FREE(req->outbuf);
3227                                 return;
3228                         }
3229
3230                         DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
3231                                 fsp->fsp_name, strerror(errno) ));
3232                         exit_server_cleanly("send_file_readX sendfile failed");
3233                 }
3234
3235                 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
3236                         fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3237                 /* No outbuf here means successful sendfile. */
3238                 TALLOC_FREE(req->outbuf);
3239                 return;
3240         }
3241 #endif
3242
3243 normal_read:
3244
3245         if ((smb_maxcnt & 0xFF0000) > 0x10000) {
3246                 uint8 headerbuf[smb_size + 2*12];
3247
3248                 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3249                 setup_readX_header((char *)headerbuf, smb_maxcnt);
3250
3251                 /* Send out the header. */
3252                 if (write_data(smbd_server_fd(), (char *)headerbuf,
3253                                sizeof(headerbuf)) != sizeof(headerbuf)) {
3254                         DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
3255                                 fsp->fsp_name, strerror(errno) ));
3256                         exit_server_cleanly("send_file_readX sendfile failed");
3257                 }
3258                 nread = fake_sendfile(fsp, startpos, smb_maxcnt);
3259                 if (nread == -1) {
3260                         DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3261                                 fsp->fsp_name, strerror(errno) ));
3262                         exit_server_cleanly("send_file_readX: fake_sendfile failed");
3263                 }
3264                 TALLOC_FREE(req->outbuf);
3265                 return;
3266         } else {
3267                 reply_outbuf(req, 12, smb_maxcnt);
3268
3269                 nread = read_file(fsp, smb_buf(req->outbuf), startpos,
3270                                   smb_maxcnt);
3271                 if (nread < 0) {
3272                         reply_unixerror(req, ERRDOS, ERRnoaccess);
3273                         return;
3274                 }
3275
3276                 setup_readX_header((char *)req->outbuf, nread);
3277
3278                 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
3279                         fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3280
3281                 chain_reply(req);
3282
3283                 return;
3284         }
3285 }
3286
3287 /****************************************************************************
3288  Reply to a read and X.
3289 ****************************************************************************/
3290
3291 void reply_read_and_X(struct smb_request *req)
3292 {
3293         connection_struct *conn = req->conn;
3294         files_struct *fsp;
3295         SMB_OFF_T startpos;
3296         size_t smb_maxcnt;
3297         bool big_readX = False;
3298 #if 0
3299         size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
3300 #endif
3301
3302         START_PROFILE(SMBreadX);
3303
3304         if ((req->wct != 10) && (req->wct != 12)) {
3305                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3306                 return;
3307         }
3308
3309         fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
3310         startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3311         smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
3312
3313         /* If it's an IPC, pass off the pipe handler. */
3314         if (IS_IPC(conn)) {
3315                 reply_pipe_read_and_X(req);
3316                 END_PROFILE(SMBreadX);
3317                 return;
3318         }
3319
3320         if (!check_fsp(conn, req, fsp)) {
3321                 END_PROFILE(SMBreadX);
3322                 return;
3323         }
3324
3325         if (!CHECK_READ(fsp,req->inbuf)) {
3326                 reply_doserror(req, ERRDOS,ERRbadaccess);
3327                 END_PROFILE(SMBreadX);
3328                 return;
3329         }
3330
3331         if (global_client_caps & CAP_LARGE_READX) {
3332                 size_t upper_size = SVAL(req->inbuf,smb_vwv7);
3333                 smb_maxcnt |= (upper_size<<16);
3334                 if (upper_size > 1) {
3335