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