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