62ca9fc1c8fb6b4910ce18592e6a9b236b039974
[samba.git] / source3 / smbd / files.c
1 /*
2    Unix SMB/CIFS implementation.
3    Files[] structure handling
4    Copyright (C) Andrew Tridgell 1998
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "smbd/smbd.h"
22 #include "smbd/globals.h"
23 #include "smbd/smbXsrv_open.h"
24 #include "libcli/security/security.h"
25 #include "util_tdb.h"
26 #include "lib/util/bitmap.h"
27 #include "lib/util/strv.h"
28
29 #define FILE_HANDLE_OFFSET 0x1000
30
31 static NTSTATUS fsp_attach_smb_fname(struct files_struct *fsp,
32                                      struct smb_filename **_smb_fname);
33
34 /**
35  * create new fsp to be used for file_new or a durable handle reconnect
36  */
37 NTSTATUS fsp_new(struct connection_struct *conn, TALLOC_CTX *mem_ctx,
38                  files_struct **result)
39 {
40         NTSTATUS status = NT_STATUS_NO_MEMORY;
41         files_struct *fsp = NULL;
42         struct smbd_server_connection *sconn = conn->sconn;
43
44         fsp = talloc_zero(mem_ctx, struct files_struct);
45         if (fsp == NULL) {
46                 goto fail;
47         }
48
49         /*
50          * This can't be a child of fsp because the file_handle can be ref'd
51          * when doing a dos/fcb open, which will then share the file_handle
52          * across multiple fsps.
53          */
54         fsp->fh = fd_handle_create(mem_ctx);
55         if (fsp->fh == NULL) {
56                 goto fail;
57         }
58
59         fsp->fsp_flags.use_ofd_locks = !lp_smbd_force_process_locks(SNUM(conn));
60 #ifndef HAVE_OFD_LOCKS
61         fsp->fsp_flags.use_ofd_locks = false;
62 #endif
63
64         fh_set_refcount(fsp->fh, 1);
65         fsp_set_fd(fsp, -1);
66
67         fsp->fnum = FNUM_FIELD_INVALID;
68         fsp->conn = conn;
69         fsp->close_write_time = make_omit_timespec();
70
71         DLIST_ADD(sconn->files, fsp);
72         sconn->num_files += 1;
73
74         conn->num_files_open++;
75
76         DBG_INFO("allocated files structure (%u used)\n",
77                 (unsigned int)sconn->num_files);
78
79         *result = fsp;
80         return NT_STATUS_OK;
81
82 fail:
83         if (fsp != NULL) {
84                 TALLOC_FREE(fsp->fh);
85         }
86         TALLOC_FREE(fsp);
87
88         return status;
89 }
90
91 void fsp_set_gen_id(files_struct *fsp)
92 {
93         static uint64_t gen_id = 1;
94
95         /*
96          * A billion of 64-bit increments per second gives us
97          * more than 500 years of runtime without wrap.
98          */
99         gen_id++;
100         fh_set_gen_id(fsp->fh, gen_id);
101 }
102
103 /****************************************************************************
104  Find first available file slot.
105 ****************************************************************************/
106
107 NTSTATUS fsp_bind_smb(struct files_struct *fsp, struct smb_request *req)
108 {
109         struct smbXsrv_open *op = NULL;
110         NTTIME now;
111         NTSTATUS status;
112
113         if (req == NULL) {
114                 DBG_DEBUG("INTERNAL_OPEN_ONLY, skipping smbXsrv_open\n");
115                 return NT_STATUS_OK;
116         }
117
118         now = timeval_to_nttime(&fsp->open_time);
119
120         status = smbXsrv_open_create(req->xconn,
121                                      fsp->conn->session_info,
122                                      now,
123                                      &op);
124         if (!NT_STATUS_IS_OK(status)) {
125                 return status;
126         }
127         fsp->op = op;
128         op->compat = fsp;
129         fsp->fnum = op->local_id;
130
131         fsp->mid = req->mid;
132         req->chain_fsp = fsp;
133
134         DBG_DEBUG("fsp [%s] mid [%" PRIu64"]\n",
135                 fsp_str_dbg(fsp), fsp->mid);
136
137         return NT_STATUS_OK;
138 }
139
140 NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
141                   files_struct **result)
142 {
143         struct smbd_server_connection *sconn = conn->sconn;
144         files_struct *fsp;
145         NTSTATUS status;
146
147         status = fsp_new(conn, conn, &fsp);
148         if (!NT_STATUS_IS_OK(status)) {
149                 return status;
150         }
151
152         GetTimeOfDay(&fsp->open_time);
153
154         status = fsp_bind_smb(fsp, req);
155         if (!NT_STATUS_IS_OK(status)) {
156                 file_free(NULL, fsp);
157                 return status;
158         }
159
160         fsp_set_gen_id(fsp);
161
162         /*
163          * Create an smb_filename with "" for the base_name.  There are very
164          * few NULL checks, so make sure it's initialized with something. to
165          * be safe until an audit can be done.
166          */
167         fsp->fsp_name = synthetic_smb_fname(fsp,
168                                             "",
169                                             NULL,
170                                             NULL,
171                                             0,
172                                             0);
173         if (fsp->fsp_name == NULL) {
174                 file_free(NULL, fsp);
175                 return NT_STATUS_NO_MEMORY;
176         }
177
178         DBG_INFO("new file %s\n", fsp_fnum_dbg(fsp));
179
180         /* A new fsp invalidates the positive and
181           negative fsp_fi_cache as the new fsp is pushed
182           at the start of the list and we search from
183           a cache hit to the *end* of the list. */
184
185         ZERO_STRUCT(sconn->fsp_fi_cache);
186
187         *result = fsp;
188         return NT_STATUS_OK;
189 }
190
191 NTSTATUS create_internal_fsp(connection_struct *conn,
192                              const struct smb_filename *smb_fname,
193                              struct files_struct **_fsp)
194 {
195         struct files_struct *fsp = NULL;
196         NTSTATUS status;
197
198         status = file_new(NULL, conn, &fsp);
199         if (!NT_STATUS_IS_OK(status)) {
200                 return status;
201         }
202
203         status = fsp_set_smb_fname(fsp, smb_fname);
204         if (!NT_STATUS_IS_OK(status)) {
205                 file_free(NULL, fsp);
206                 return status;
207         }
208
209         *_fsp = fsp;
210         return NT_STATUS_OK;
211 }
212
213 /*
214  * Create an internal fsp for an *existing* directory.
215  *
216  * This should only be used by callers in the VFS that need to control the
217  * opening of the directory. Otherwise use open_internal_dirfsp_at().
218  */
219 NTSTATUS create_internal_dirfsp(connection_struct *conn,
220                                 const struct smb_filename *smb_dname,
221                                 struct files_struct **_fsp)
222 {
223         struct files_struct *fsp = NULL;
224         NTSTATUS status;
225
226         status = create_internal_fsp(conn, smb_dname, &fsp);
227         if (!NT_STATUS_IS_OK(status)) {
228                 return status;
229         }
230
231         fsp->access_mask = FILE_LIST_DIRECTORY;
232         fsp->fsp_flags.is_directory = true;
233         fsp->fsp_flags.is_dirfsp = true;
234
235         *_fsp = fsp;
236         return NT_STATUS_OK;
237 }
238
239 /*
240  * Open an internal fsp for an *existing* directory.
241  */
242 NTSTATUS open_internal_dirfsp(connection_struct *conn,
243                               const struct smb_filename *smb_dname,
244                               int open_flags,
245                               struct files_struct **_fsp)
246 {
247         struct files_struct *fsp = NULL;
248         NTSTATUS status;
249
250         status = create_internal_dirfsp(conn, smb_dname, &fsp);
251         if (!NT_STATUS_IS_OK(status)) {
252                 return status;
253         }
254
255 #ifdef O_DIRECTORY
256         open_flags |= O_DIRECTORY;
257 #endif
258         status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, open_flags, 0);
259         if (!NT_STATUS_IS_OK(status)) {
260                 DBG_INFO("Could not open fd for %s (%s)\n",
261                          smb_fname_str_dbg(smb_dname),
262                          nt_errstr(status));
263                 file_free(NULL, fsp);
264                 return status;
265         }
266
267         status = vfs_stat_fsp(fsp);
268         if (!NT_STATUS_IS_OK(status)) {
269                 file_free(NULL, fsp);
270                 return status;
271         }
272
273         if (!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
274                 DBG_ERR("%s is not a directory!\n",
275                         smb_fname_str_dbg(smb_dname));
276                 file_free(NULL, fsp);
277                 return NT_STATUS_NOT_A_DIRECTORY;
278         }
279
280         fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
281
282         *_fsp = fsp;
283         return NT_STATUS_OK;
284 }
285
286 /*
287  * Convert a pathref dirfsp into a real fsp. No need to do any cwd
288  * tricks, we just open ".".
289  */
290 NTSTATUS openat_internal_dir_from_pathref(
291         struct files_struct *dirfsp,
292         int open_flags,
293         struct files_struct **_fsp)
294 {
295         struct connection_struct *conn = dirfsp->conn;
296         struct smb_filename *smb_dname = dirfsp->fsp_name;
297         struct files_struct *fsp = NULL;
298         char dot[] = ".";
299         struct smb_filename smb_dot = {
300                 .base_name = dot,
301                 .flags = smb_dname->flags,
302                 .twrp = smb_dname->twrp,
303         };
304         NTSTATUS status;
305
306         status = create_internal_dirfsp(conn, smb_dname, &fsp);
307         if (!NT_STATUS_IS_OK(status)) {
308                 return status;
309         }
310
311         /*
312          * Pointless for opening ".", but you never know...
313          */
314         open_flags |= O_NOFOLLOW;
315
316         status = fd_openat(dirfsp, &smb_dot, fsp, open_flags, 0);
317         if (!NT_STATUS_IS_OK(status)) {
318                 DBG_INFO("fd_openat(\"%s\", \".\") failed: %s\n",
319                          fsp_str_dbg(dirfsp),
320                          nt_errstr(status));
321                 file_free(NULL, fsp);
322                 return status;
323         }
324
325         fsp->fsp_name->st = smb_dname->st;
326         fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
327         *_fsp = fsp;
328         return NT_STATUS_OK;
329 }
330
331 /*
332  * The "link" in the name doesn't imply link in the filesystem
333  * sense. It's a object that "links" together an fsp and an smb_fname
334  * and the link allocated as talloc child of an fsp.
335  *
336  * The link is created for fsps that openat_pathref_fsp() returns in
337  * smb_fname->fsp. When this fsp is freed by file_free() by some caller
338  * somewhere, the destructor fsp_smb_fname_link_destructor() on the link object
339  * will use the link to reset the reference in smb_fname->fsp that is about to
340  * go away.
341  *
342  * This prevents smb_fname_internal_fsp_destructor() from seeing dangling fsp
343  * pointers.
344  */
345
346 struct fsp_smb_fname_link {
347         struct fsp_smb_fname_link **smb_fname_link;
348         struct files_struct **smb_fname_fsp;
349 };
350
351 static int fsp_smb_fname_link_destructor(struct fsp_smb_fname_link *link)
352 {
353         if (link->smb_fname_link == NULL) {
354                 return 0;
355         }
356
357         *link->smb_fname_link = NULL;
358         *link->smb_fname_fsp = NULL;
359         return 0;
360 }
361
362 static NTSTATUS fsp_smb_fname_link(struct files_struct *fsp,
363                                    struct fsp_smb_fname_link **smb_fname_link,
364                                    struct files_struct **smb_fname_fsp)
365 {
366         struct fsp_smb_fname_link *link = NULL;
367
368         SMB_ASSERT(*smb_fname_link == NULL);
369         SMB_ASSERT(*smb_fname_fsp == NULL);
370
371         link = talloc_zero(fsp, struct fsp_smb_fname_link);
372         if (link == NULL) {
373                 return NT_STATUS_NO_MEMORY;
374         }
375
376         link->smb_fname_link = smb_fname_link;
377         link->smb_fname_fsp = smb_fname_fsp;
378         *smb_fname_link = link;
379         *smb_fname_fsp = fsp;
380
381         talloc_set_destructor(link, fsp_smb_fname_link_destructor);
382         return NT_STATUS_OK;
383 }
384
385 /*
386  * Free a link, carefully avoiding to trigger the link destructor
387  */
388 static void destroy_fsp_smb_fname_link(struct fsp_smb_fname_link **_link)
389 {
390         struct fsp_smb_fname_link *link = *_link;
391
392         if (link == NULL) {
393                 return;
394         }
395         talloc_set_destructor(link, NULL);
396         TALLOC_FREE(link);
397         *_link = NULL;
398 }
399
400 /*
401  * Talloc destructor set on an smb_fname set by openat_pathref_fsp() used to
402  * close the embedded smb_fname->fsp.
403  */
404 static int smb_fname_fsp_destructor(struct smb_filename *smb_fname)
405 {
406         struct files_struct *fsp = smb_fname->fsp;
407         NTSTATUS status;
408         int saved_errno = errno;
409
410         destroy_fsp_smb_fname_link(&smb_fname->fsp_link);
411
412         if (fsp == NULL) {
413                 errno = saved_errno;
414                 return 0;
415         }
416
417         if (fsp_is_alternate_stream(fsp)) {
418                 struct files_struct *tmp_base_fsp = fsp->base_fsp;
419
420                 fsp_set_base_fsp(fsp, NULL);
421
422                 status = fd_close(tmp_base_fsp);
423                 if (!NT_STATUS_IS_OK(status)) {
424                         DBG_ERR("Closing fd for fsp [%s] failed: %s. "
425                                 "Please check your filesystem!!!\n",
426                                 fsp_str_dbg(fsp), nt_errstr(status));
427                 }
428                 file_free(NULL, tmp_base_fsp);
429         }
430
431         status = fd_close(fsp);
432         if (!NT_STATUS_IS_OK(status)) {
433                 DBG_ERR("Closing fd for fsp [%s] failed: %s. "
434                         "Please check your filesystem!!!\n",
435                         fsp_str_dbg(fsp), nt_errstr(status));
436         }
437         file_free(NULL, fsp);
438         smb_fname->fsp = NULL;
439
440         errno = saved_errno;
441         return 0;
442 }
443
444 static NTSTATUS openat_pathref_fullname(
445         struct connection_struct *conn,
446         const struct files_struct *dirfsp,
447         struct files_struct *basefsp,
448         struct smb_filename **full_fname,
449         struct smb_filename *smb_fname)
450 {
451         struct files_struct *fsp = NULL;
452         bool have_dirfsp = (dirfsp != NULL);
453         bool have_basefsp = (basefsp != NULL);
454         NTSTATUS status;
455
456         DBG_DEBUG("smb_fname [%s]\n", smb_fname_str_dbg(smb_fname));
457
458         SMB_ASSERT(smb_fname->fsp == NULL);
459         SMB_ASSERT(have_dirfsp != have_basefsp);
460
461         status = fsp_new(conn, conn, &fsp);
462         if (!NT_STATUS_IS_OK(status)) {
463                 return status;
464         }
465
466         GetTimeOfDay(&fsp->open_time);
467         fsp_set_gen_id(fsp);
468         ZERO_STRUCT(conn->sconn->fsp_fi_cache);
469
470         fsp->fsp_flags.is_pathref = true;
471
472         status = fsp_attach_smb_fname(fsp, full_fname);
473         if (!NT_STATUS_IS_OK(status)) {
474                 goto fail;
475         }
476         fsp_set_base_fsp(fsp, basefsp);
477
478         status = fd_openat(
479                 dirfsp, smb_fname, fsp, O_RDONLY|O_NONBLOCK, 0);
480         if (!NT_STATUS_IS_OK(status)) {
481
482                 smb_fname->st = fsp->fsp_name->st;
483
484                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) ||
485                     NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
486                     NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK))
487                 {
488                         /*
489                          * streams_xattr return NT_STATUS_NOT_FOUND for
490                          * opens of not yet existing streams.
491                          *
492                          * ELOOP maps to NT_STATUS_OBJECT_PATH_NOT_FOUND
493                          * and this will result from a open request from
494                          * a POSIX client on a symlink.
495                          *
496                          * NT_STATUS_OBJECT_NAME_NOT_FOUND is the simple
497                          * ENOENT case.
498                          *
499                          * NT_STATUS_STOPPED_ON_SYMLINK is returned when trying
500                          * to open a symlink, our callers are not interested in
501                          * this.
502                          */
503                         status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
504                 }
505                 goto fail;
506         }
507
508         /*
509          * fd_openat() has done an FSTAT on the handle
510          * so update the smb_fname stat info with "truth".
511          * from the handle.
512          */
513         smb_fname->st = fsp->fsp_name->st;
514
515         fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
516
517         fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
518
519         status = fsp_smb_fname_link(fsp,
520                                     &smb_fname->fsp_link,
521                                     &smb_fname->fsp);
522         if (!NT_STATUS_IS_OK(status)) {
523                 goto fail;
524         }
525
526         DBG_DEBUG("fsp [%s]: OK\n", fsp_str_dbg(fsp));
527
528         talloc_set_destructor(smb_fname, smb_fname_fsp_destructor);
529         return NT_STATUS_OK;
530
531 fail:
532         DBG_DEBUG("Opening pathref for [%s] failed: %s\n",
533                   smb_fname_str_dbg(smb_fname),
534                   nt_errstr(status));
535
536         fsp_set_base_fsp(fsp, NULL);
537         fd_close(fsp);
538         file_free(NULL, fsp);
539         return status;
540 }
541
542 /*
543  * Open an internal O_PATH based fsp for smb_fname. If O_PATH is not
544  * available, open O_RDONLY as root. Both is done in fd_open() ->
545  * non_widelink_open(), triggered by setting fsp->fsp_flags.is_pathref to
546  * true.
547  */
548 NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp,
549                             struct smb_filename *smb_fname)
550 {
551         connection_struct *conn = dirfsp->conn;
552         struct smb_filename *full_fname = NULL;
553         struct smb_filename *base_fname = NULL;
554         NTSTATUS status;
555
556         DBG_DEBUG("smb_fname [%s]\n", smb_fname_str_dbg(smb_fname));
557
558         if (smb_fname->fsp != NULL) {
559                 /* We already have one for this name. */
560                 DBG_DEBUG("smb_fname [%s] already has a pathref fsp.\n",
561                         smb_fname_str_dbg(smb_fname));
562                 return NT_STATUS_OK;
563         }
564
565         if (!(conn->fs_capabilities & FILE_NAMED_STREAMS) ||
566             !is_named_stream(smb_fname)) {
567                 /*
568                  * openat_pathref_fullname() will make "full_fname" a
569                  * talloc child of the smb_fname->fsp. Don't use
570                  * talloc_tos() to allocate it to avoid making the
571                  * talloc stackframe pool long-lived.
572                  */
573                 full_fname = full_path_from_dirfsp_atname(
574                         conn,
575                         dirfsp,
576                         smb_fname);
577                 if (full_fname == NULL) {
578                         status = NT_STATUS_NO_MEMORY;
579                         goto fail;
580                 }
581                 status = openat_pathref_fullname(
582                         conn, dirfsp, NULL, &full_fname, smb_fname);
583                 TALLOC_FREE(full_fname);
584                 return status;
585         }
586
587         /*
588          * stream open
589          */
590         base_fname = cp_smb_filename_nostream(conn, smb_fname);
591         if (base_fname == NULL) {
592                 return NT_STATUS_NO_MEMORY;
593         }
594
595         full_fname = full_path_from_dirfsp_atname(
596                 conn,   /* no talloc_tos(), see comment above */
597                 dirfsp,
598                 base_fname);
599         if (full_fname == NULL) {
600                 status = NT_STATUS_NO_MEMORY;
601                 goto fail;
602         }
603
604         status = openat_pathref_fullname(
605                 conn, dirfsp, NULL, &full_fname, base_fname);
606         TALLOC_FREE(full_fname);
607         if (!NT_STATUS_IS_OK(status)) {
608                 DBG_DEBUG("openat_pathref_nostream failed: %s\n",
609                           nt_errstr(status));
610                 goto fail;
611         }
612
613         status = open_stream_pathref_fsp(&base_fname->fsp, smb_fname);
614         if (!NT_STATUS_IS_OK(status)) {
615                 DBG_DEBUG("open_stream_pathref_fsp failed: %s\n",
616                           nt_errstr(status));
617                 goto fail;
618         }
619
620         smb_fname_fsp_unlink(base_fname);
621 fail:
622         TALLOC_FREE(base_fname);
623         return status;
624 }
625
626 /*
627  * Open a stream given an already opened base_fsp. Avoid
628  * non_widelink_open: This is only valid for the case where we have a
629  * valid non-cwd_fsp dirfsp that we can pass to SMB_VFS_OPENAT()
630  */
631 NTSTATUS open_stream_pathref_fsp(
632         struct files_struct **_base_fsp,
633         struct smb_filename *smb_fname)
634 {
635         struct files_struct *base_fsp = *_base_fsp;
636         connection_struct *conn = base_fsp->conn;
637         struct smb_filename *base_fname = base_fsp->fsp_name;
638         struct smb_filename *full_fname = NULL;
639         NTSTATUS status;
640
641         SMB_ASSERT(smb_fname->fsp == NULL);
642         SMB_ASSERT(is_named_stream(smb_fname));
643
644         full_fname = synthetic_smb_fname(
645                 conn, /* no talloc_tos(), this will be long-lived */
646                 base_fname->base_name,
647                 smb_fname->stream_name,
648                 &smb_fname->st,
649                 smb_fname->twrp,
650                 smb_fname->flags);
651         if (full_fname == NULL) {
652                 return NT_STATUS_NO_MEMORY;
653         }
654
655         status = openat_pathref_fullname(
656                 conn, NULL, base_fsp, &full_fname, smb_fname);
657         TALLOC_FREE(full_fname);
658         return status;
659 }
660
661 static char *path_to_strv(TALLOC_CTX *mem_ctx, const char *path)
662 {
663         char *result = talloc_strdup(mem_ctx, path);
664
665         if (result == NULL) {
666                 return NULL;
667         }
668         string_replace(result, '/', '\0');
669         return result;
670 }
671
672 static NTSTATUS readlink_talloc(
673         TALLOC_CTX *mem_ctx,
674         struct files_struct *dirfsp,
675         struct smb_filename *smb_relname,
676         char **_substitute)
677 {
678         char buf[4096];
679         ssize_t ret;
680         char *substitute;
681         NTSTATUS status;
682
683         if (_substitute == NULL) {
684                 return NT_STATUS_OK;
685         }
686
687         if (smb_relname == NULL) {
688                 /*
689                  * We have a Linux O_PATH handle in dirfsp and want to
690                  * read its value, essentially a freadlink
691                  */
692                 smb_relname = synthetic_smb_fname(
693                         talloc_tos(), "", NULL, NULL, 0, 0);
694                 if (smb_relname == NULL) {
695                         DBG_DEBUG("synthetic_smb_fname() failed\n");
696                         return NT_STATUS_NO_MEMORY;
697                 }
698         }
699
700         ret = SMB_VFS_READLINKAT(
701                 dirfsp->conn, dirfsp, smb_relname, buf, sizeof(buf));
702         if (ret < 0) {
703                 status = map_nt_error_from_unix(errno);
704                 DBG_DEBUG("SMB_VFS_READLINKAT() failed: %s\n",
705                           strerror(errno));
706                 return status;
707         }
708
709         if ((size_t)ret == sizeof(buf)) {
710                 /*
711                  * Do we need symlink targets >4k?
712                  */
713                 DBG_DEBUG("Got full %zu bytes from readlink, too long\n",
714                           sizeof(buf));
715                 return NT_STATUS_BUFFER_OVERFLOW;
716         }
717
718         substitute = talloc_strndup(mem_ctx, buf, ret);
719         if (substitute == NULL) {
720                 DBG_DEBUG("talloc_strndup() failed\n");
721                 return NT_STATUS_NO_MEMORY;
722         }
723
724         *_substitute = substitute;
725         return NT_STATUS_OK;
726 }
727
728 NTSTATUS openat_pathref_dirfsp_nosymlink(
729         TALLOC_CTX *mem_ctx,
730         struct connection_struct *conn,
731         const char *path_in,
732         NTTIME twrp,
733         struct smb_filename **_smb_fname,
734         size_t *unparsed,
735         char **substitute)
736 {
737         struct files_struct *dirfsp = conn->cwd_fsp;
738         struct smb_filename full_fname = {
739                 .base_name = NULL,
740                 .twrp = twrp,
741         };
742         struct smb_filename rel_fname = {
743                 .base_name = NULL,
744                 .twrp = twrp,
745         };
746         struct smb_filename *result = NULL;
747         struct files_struct *fsp = NULL;
748         char *path = NULL, *next = NULL;
749         int flags = O_NOFOLLOW|O_DIRECTORY;
750         int fd;
751         NTSTATUS status;
752
753         DBG_DEBUG("path_in=%s\n", path_in);
754
755         status = fsp_new(conn, conn, &fsp);
756         if (!NT_STATUS_IS_OK(status)) {
757                 DBG_DEBUG("fsp_new() failed: %s\n", nt_errstr(status));
758                 goto fail;
759         }
760         fsp->fsp_name = &full_fname;
761
762 #ifdef O_PATH
763         /*
764          * Add O_PATH manually, doing this by setting
765          * fsp->fsp_flags.is_pathref will make us become_root() in the
766          * non-O_PATH case, which would cause a security problem.
767          */
768         flags |= O_PATH;
769 #else
770 #ifdef O_SEARCH
771         /*
772          * O_SEARCH just checks for the "x" bit. We are traversing
773          * directories, so we don't need the implicit O_RDONLY ("r"
774          * permissions) but only the "x"-permissions requested by
775          * O_SEARCH. We need either O_PATH or O_SEARCH to correctly
776          * function, without either we will incorrectly require also
777          * the "r" bit when traversing the directory hierarchy.
778          */
779         flags |= O_SEARCH;
780 #endif
781 #endif
782
783         full_fname.base_name = talloc_strdup(talloc_tos(), "");
784         if (full_fname.base_name == NULL) {
785                 DBG_DEBUG("talloc_strdup() failed\n");
786                 goto nomem;
787         }
788
789         path = path_to_strv(talloc_tos(), path_in);
790         if (path == NULL) {
791                 DBG_DEBUG("path_to_strv() failed\n");
792                 goto nomem;
793         }
794         rel_fname.base_name = path;
795
796 next:
797         next = strv_next(path, rel_fname.base_name);
798
799         if (ISDOT(rel_fname.base_name) || ISDOTDOT(rel_fname.base_name)) {
800                 DBG_DEBUG("%s contains a dot\n", path_in);
801                 status = NT_STATUS_OBJECT_NAME_INVALID;
802                 goto fail;
803         }
804
805         fd = SMB_VFS_OPENAT(
806                 conn,
807                 dirfsp,
808                 &rel_fname,
809                 fsp,
810                 flags,
811                 0);
812
813         if ((fd == -1) && (errno == ENOENT)) {
814                 status = get_real_filename_at(
815                         dirfsp,
816                         rel_fname.base_name,
817                         talloc_tos(),
818                         &rel_fname.base_name);
819
820                 if (!NT_STATUS_IS_OK(status)) {
821                         DBG_DEBUG("get_real_filename_at failed: %s\n",
822                                   nt_errstr(status));
823                         goto fail;
824                 }
825
826                 fd = SMB_VFS_OPENAT(
827                         conn,
828                         dirfsp,
829                         &rel_fname,
830                         fsp,
831                         flags,
832                         0);
833         }
834
835         if ((fd == -1) && (errno == ENOTDIR)) {
836                 status = readlink_talloc(
837                         mem_ctx, dirfsp, &rel_fname, substitute);
838
839                 if (NT_STATUS_IS_OK(status)) {
840                         /*
841                          * readlink_talloc() found a symlink
842                          */
843                         status = NT_STATUS_STOPPED_ON_SYMLINK;
844
845                         if (unparsed != NULL) {
846                                 if (next == NULL) {
847                                         *unparsed = 0;
848                                 } else {
849                                         size_t parsed = next - path;
850                                         size_t len = talloc_get_size(path);
851                                         *unparsed = len - parsed;
852                                 }
853                         }
854                 } else {
855
856                         DBG_DEBUG("readlink_talloc failed: %s\n",
857                                   nt_errstr(status));
858                         /*
859                          * Restore the error status from SMB_VFS_OPENAT()
860                          */
861                         status = NT_STATUS_NOT_A_DIRECTORY;
862                 }
863                 goto fail;
864         }
865
866         if (fd == -1) {
867                 status = map_nt_error_from_unix(errno);
868                 DBG_DEBUG("SMB_VFS_OPENAT() failed: %s\n",
869                           strerror(errno));
870                 goto fail;
871         }
872         fsp_set_fd(fsp, fd);
873
874         fsp->fsp_flags.is_directory = true; /* See O_DIRECTORY above */
875
876         full_fname.base_name = talloc_asprintf_append_buffer(
877                         full_fname.base_name,
878                         "%s%s",
879                         full_fname.base_name[0] == '\0' ? "" : "/",
880                         rel_fname.base_name);
881
882         if (full_fname.base_name == NULL) {
883                 DBG_DEBUG("talloc_asprintf_append_buffer() failed\n");
884                 goto nomem;
885         }
886
887         if (next != NULL) {
888                 struct files_struct *tmp = NULL;
889
890                 if (dirfsp != conn->cwd_fsp) {
891                         fd_close(dirfsp);
892                 }
893
894                 tmp = dirfsp;
895                 dirfsp = fsp;
896
897                 if (tmp == conn->cwd_fsp) {
898                         status = fsp_new(conn, conn, &fsp);
899                         if (!NT_STATUS_IS_OK(status)) {
900                                 DBG_DEBUG("fsp_new() failed: %s\n",
901                                           nt_errstr(status));
902                                 goto fail;
903                         }
904                         fsp->fsp_name = &full_fname;
905                 } else {
906                         fsp = tmp;
907                 }
908
909                 rel_fname.base_name = next;
910
911                 goto next;
912         }
913
914         if (dirfsp != conn->cwd_fsp) {
915                 dirfsp->fsp_name = NULL;
916                 SMB_ASSERT(fsp_get_pathref_fd(dirfsp) != -1);
917                 fd_close(dirfsp);
918                 file_free(NULL, dirfsp);
919                 dirfsp = NULL;
920         }
921
922         fsp->fsp_flags.is_pathref = true;
923         fsp->fsp_name = NULL;
924
925         status = fsp_set_smb_fname(fsp, &full_fname);
926         if (!NT_STATUS_IS_OK(status)) {
927                 DBG_DEBUG("fsp_set_smb_fname() failed: %s\n",
928                           nt_errstr(status));
929                 goto fail;
930         }
931
932         status = vfs_stat_fsp(fsp);
933         if (!NT_STATUS_IS_OK(status)) {
934                 DBG_DEBUG("vfs_stat_fsp(%s) failed: %s\n",
935                           fsp_str_dbg(fsp),
936                           nt_errstr(status));
937                 goto fail;
938         }
939         /*
940          * We must correctly set fsp->file_id as code inside
941          * open.c will use this to check if delete_on_close
942          * has been set on the dirfsp.
943          */
944         fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
945
946         result = cp_smb_filename(mem_ctx, fsp->fsp_name);
947         if (result == NULL) {
948                 DBG_DEBUG("cp_smb_filename() failed\n");
949                 goto nomem;
950         }
951
952         status = fsp_smb_fname_link(fsp,
953                                         &result->fsp_link,
954                                         &result->fsp);
955         if (!NT_STATUS_IS_OK(status)) {
956                 goto fail;
957         }
958         talloc_set_destructor(result, smb_fname_fsp_destructor);
959
960         *_smb_fname = result;
961
962         DBG_DEBUG("returning %s\n", smb_fname_str_dbg(result));
963
964         return NT_STATUS_OK;
965
966 nomem:
967         status = NT_STATUS_NO_MEMORY;
968 fail:
969         if (fsp != NULL) {
970                 if (fsp_get_pathref_fd(fsp) != -1) {
971                         fd_close(fsp);
972                 }
973                 file_free(NULL, fsp);
974                 fsp = NULL;
975         }
976
977         if ((dirfsp != NULL) && (dirfsp != conn->cwd_fsp)) {
978                 dirfsp->fsp_name = NULL;
979                 SMB_ASSERT(fsp_get_pathref_fd(dirfsp) != -1);
980                 fd_close(dirfsp);
981                 file_free(NULL, dirfsp);
982                 dirfsp = NULL;
983         }
984
985         TALLOC_FREE(path);
986         return status;
987 }
988
989 void smb_fname_fsp_unlink(struct smb_filename *smb_fname)
990 {
991         talloc_set_destructor(smb_fname, NULL);
992         smb_fname->fsp = NULL;
993         destroy_fsp_smb_fname_link(&smb_fname->fsp_link);
994 }
995
996 /*
997  * Move any existing embedded fsp refs from the src name to the
998  * destination. It's safe to call this on src smb_fname's that have no embedded
999  * pathref fsp.
1000  */
1001 NTSTATUS move_smb_fname_fsp_link(struct smb_filename *smb_fname_dst,
1002                                  struct smb_filename *smb_fname_src)
1003 {
1004         NTSTATUS status;
1005
1006         /*
1007          * The target should always not be linked yet!
1008          */
1009         SMB_ASSERT(smb_fname_dst->fsp == NULL);
1010         SMB_ASSERT(smb_fname_dst->fsp_link == NULL);
1011
1012         if (smb_fname_src->fsp == NULL) {
1013                 return NT_STATUS_OK;
1014         }
1015
1016         status = fsp_smb_fname_link(smb_fname_src->fsp,
1017                                     &smb_fname_dst->fsp_link,
1018                                     &smb_fname_dst->fsp);
1019         if (!NT_STATUS_IS_OK(status)) {
1020                 return status;
1021         }
1022
1023         talloc_set_destructor(smb_fname_dst, smb_fname_fsp_destructor);
1024
1025         smb_fname_fsp_unlink(smb_fname_src);
1026
1027         return NT_STATUS_OK;
1028 }
1029
1030 /**
1031  * Create an smb_fname and open smb_fname->fsp pathref
1032  **/
1033 NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx,
1034                            struct files_struct *dirfsp,
1035                            const char *base_name,
1036                            const char *stream_name,
1037                            const SMB_STRUCT_STAT *psbuf,
1038                            NTTIME twrp,
1039                            uint32_t flags,
1040                            struct smb_filename **_smb_fname)
1041 {
1042         struct smb_filename *smb_fname = NULL;
1043         NTSTATUS status;
1044
1045         smb_fname = synthetic_smb_fname(mem_ctx,
1046                                         base_name,
1047                                         stream_name,
1048                                         psbuf,
1049                                         twrp,
1050                                         flags);
1051         if (smb_fname == NULL) {
1052                 return NT_STATUS_NO_MEMORY;
1053         }
1054
1055         status = openat_pathref_fsp(dirfsp, smb_fname);
1056         if (!NT_STATUS_IS_OK(status)) {
1057                 DBG_ERR("opening [%s] failed\n",
1058                         smb_fname_str_dbg(smb_fname));
1059                 TALLOC_FREE(smb_fname);
1060                 return status;
1061         }
1062
1063         *_smb_fname = smb_fname;
1064         return NT_STATUS_OK;
1065 }
1066
1067 static int atname_destructor(struct smb_filename *smb_fname)
1068 {
1069         destroy_fsp_smb_fname_link(&smb_fname->fsp_link);
1070         return 0;
1071 }
1072
1073 /**
1074  * Turn a path into a parent pathref and atname
1075  *
1076  * This returns the parent pathref in _parent and the name relative to it. If
1077  * smb_fname was a pathref (ie smb_fname->fsp != NULL), then _atname will be a
1078  * pathref as well, ie _atname->fsp will point at the same fsp as
1079  * smb_fname->fsp.
1080  **/
1081 NTSTATUS parent_pathref(TALLOC_CTX *mem_ctx,
1082                         struct files_struct *dirfsp,
1083                         const struct smb_filename *smb_fname,
1084                         struct smb_filename **_parent,
1085                         struct smb_filename **_atname)
1086 {
1087         struct smb_filename *parent = NULL;
1088         struct smb_filename *atname = NULL;
1089         NTSTATUS status;
1090
1091         status = SMB_VFS_PARENT_PATHNAME(dirfsp->conn,
1092                                          mem_ctx,
1093                                          smb_fname,
1094                                          &parent,
1095                                          &atname);
1096         if (!NT_STATUS_IS_OK(status)) {
1097                 return status;
1098         }
1099
1100         /*
1101          * We know that the parent name must
1102          * exist, and the name has been canonicalized
1103          * even if this was a POSIX pathname.
1104          * Ensure that we follow symlinks for
1105          * the parent. See the torture test
1106          * POSIX-SYMLINK-PARENT for details.
1107          */
1108         parent->flags &= ~SMB_FILENAME_POSIX_PATH;
1109
1110         status = openat_pathref_fsp(dirfsp, parent);
1111         if (!NT_STATUS_IS_OK(status)) {
1112                 TALLOC_FREE(parent);
1113                 return status;
1114         }
1115
1116         if (smb_fname->fsp != NULL) {
1117                 status = fsp_smb_fname_link(smb_fname->fsp,
1118                                             &atname->fsp_link,
1119                                             &atname->fsp);
1120                 if (!NT_STATUS_IS_OK(status)) {
1121                         TALLOC_FREE(parent);
1122                         return status;
1123                 }
1124                 talloc_set_destructor(atname, atname_destructor);
1125         }
1126         *_parent = parent;
1127         *_atname = atname;
1128         return NT_STATUS_OK;
1129 }
1130
1131 static bool close_file_in_loop(struct files_struct *fsp)
1132 {
1133         if (fsp_is_alternate_stream(fsp)) {
1134                 /*
1135                  * This is a stream, it can't be a base
1136                  */
1137                 SMB_ASSERT(fsp->stream_fsp == NULL);
1138                 SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
1139
1140                 /*
1141                  * Remove the base<->stream link so that
1142                  * close_file_free() does not close fsp->base_fsp as
1143                  * well. This would destroy walking the linked list of
1144                  * fsps.
1145                  */
1146                 fsp->base_fsp->stream_fsp = NULL;
1147                 fsp->base_fsp = NULL;
1148
1149                 close_file_free(NULL, &fsp, SHUTDOWN_CLOSE);
1150                 return NULL;
1151         }
1152
1153         if (fsp->stream_fsp != NULL) {
1154                 /*
1155                  * This is the base of a stream.
1156                  */
1157                 SMB_ASSERT(fsp->stream_fsp->base_fsp == fsp);
1158
1159                 /*
1160                  * Remove the base<->stream link. This will make fsp
1161                  * look like a normal fsp for the next round.
1162                  */
1163                 fsp->stream_fsp->base_fsp = NULL;
1164                 fsp->stream_fsp = NULL;
1165
1166                 /*
1167                  * Have us called back a second time. In the second
1168                  * round, "fsp" now looks like a normal fsp.
1169                  */
1170                 return false;
1171         }
1172
1173         close_file_free(NULL, &fsp, SHUTDOWN_CLOSE);
1174         return true;
1175 }
1176
1177 /****************************************************************************
1178  Close all open files for a connection.
1179 ****************************************************************************/
1180
1181 struct file_close_conn_state {
1182         struct connection_struct *conn;
1183         bool fsp_left_behind;
1184 };
1185
1186 static struct files_struct *file_close_conn_fn(
1187         struct files_struct *fsp,
1188         void *private_data)
1189 {
1190         struct file_close_conn_state *state = private_data;
1191         bool did_close;
1192
1193         if (fsp->conn != state->conn) {
1194                 return NULL;
1195         }
1196
1197         if (fsp->op != NULL && fsp->op->global->durable) {
1198                 /*
1199                  * A tree disconnect closes a durable handle
1200                  */
1201                 fsp->op->global->durable = false;
1202         }
1203
1204         did_close = close_file_in_loop(fsp);
1205         if (!did_close) {
1206                 state->fsp_left_behind = true;
1207         }
1208
1209         return NULL;
1210 }
1211
1212 void file_close_conn(connection_struct *conn)
1213 {
1214         struct file_close_conn_state state = { .conn = conn };
1215
1216         files_forall(conn->sconn, file_close_conn_fn, &state);
1217
1218         if (state.fsp_left_behind) {
1219                 state.fsp_left_behind = false;
1220                 files_forall(conn->sconn, file_close_conn_fn, &state);
1221                 SMB_ASSERT(!state.fsp_left_behind);
1222         }
1223 }
1224
1225 /****************************************************************************
1226  Initialise file structures.
1227 ****************************************************************************/
1228
1229 static int files_max_open_fds;
1230
1231 bool file_init_global(void)
1232 {
1233         int request_max = lp_max_open_files();
1234         int real_lim;
1235         int real_max;
1236
1237         if (files_max_open_fds != 0) {
1238                 return true;
1239         }
1240
1241         /*
1242          * Set the max_open files to be the requested
1243          * max plus a fudgefactor to allow for the extra
1244          * fd's we need such as log files etc...
1245          */
1246         real_lim = set_maxfiles(request_max + MAX_OPEN_FUDGEFACTOR);
1247
1248         real_max = real_lim - MAX_OPEN_FUDGEFACTOR;
1249
1250         if (real_max + FILE_HANDLE_OFFSET + MAX_OPEN_PIPES > 65536) {
1251                 real_max = 65536 - FILE_HANDLE_OFFSET - MAX_OPEN_PIPES;
1252         }
1253
1254         if (real_max != request_max) {
1255                 DEBUG(1, ("file_init_global: Information only: requested %d "
1256                           "open files, %d are available.\n",
1257                           request_max, real_max));
1258         }
1259
1260         SMB_ASSERT(real_max > 100);
1261
1262         files_max_open_fds = real_max;
1263         return true;
1264 }
1265
1266 bool file_init(struct smbd_server_connection *sconn)
1267 {
1268         bool ok;
1269
1270         ok = file_init_global();
1271         if (!ok) {
1272                 return false;
1273         }
1274
1275         sconn->real_max_open_files = files_max_open_fds;
1276
1277         return true;
1278 }
1279
1280 /****************************************************************************
1281  Close files open by a specified vuid.
1282 ****************************************************************************/
1283
1284 struct file_close_user_state {
1285         uint64_t vuid;
1286         bool fsp_left_behind;
1287 };
1288
1289 static struct files_struct *file_close_user_fn(
1290         struct files_struct *fsp,
1291         void *private_data)
1292 {
1293         struct file_close_user_state *state = private_data;
1294         bool did_close;
1295
1296         if (fsp->vuid != state->vuid) {
1297                 return NULL;
1298         }
1299
1300         did_close = close_file_in_loop(fsp);
1301         if (!did_close) {
1302                 state->fsp_left_behind = true;
1303         }
1304
1305         return NULL;
1306 }
1307
1308 void file_close_user(struct smbd_server_connection *sconn, uint64_t vuid)
1309 {
1310         struct file_close_user_state state = { .vuid = vuid };
1311
1312         files_forall(sconn, file_close_user_fn, &state);
1313
1314         if (state.fsp_left_behind) {
1315                 state.fsp_left_behind = false;
1316                 files_forall(sconn, file_close_user_fn, &state);
1317                 SMB_ASSERT(!state.fsp_left_behind);
1318         }
1319 }
1320
1321 /*
1322  * Walk the files table until "fn" returns non-NULL
1323  */
1324
1325 struct files_struct *files_forall(
1326         struct smbd_server_connection *sconn,
1327         struct files_struct *(*fn)(struct files_struct *fsp,
1328                                    void *private_data),
1329         void *private_data)
1330 {
1331         struct files_struct *fsp, *next;
1332
1333         for (fsp = sconn->files; fsp; fsp = next) {
1334                 struct files_struct *ret;
1335                 next = fsp->next;
1336                 ret = fn(fsp, private_data);
1337                 if (ret != NULL) {
1338                         return ret;
1339                 }
1340         }
1341         return NULL;
1342 }
1343
1344 /****************************************************************************
1345  Find a fsp given a file descriptor.
1346 ****************************************************************************/
1347
1348 files_struct *file_find_fd(struct smbd_server_connection *sconn, int fd)
1349 {
1350         int count=0;
1351         files_struct *fsp;
1352
1353         for (fsp=sconn->files; fsp; fsp=fsp->next,count++) {
1354                 if (fsp_get_pathref_fd(fsp) == fd) {
1355                         if (count > 10) {
1356                                 DLIST_PROMOTE(sconn->files, fsp);
1357                         }
1358                         return fsp;
1359                 }
1360         }
1361
1362         return NULL;
1363 }
1364
1365 /****************************************************************************
1366  Find a fsp given a device, inode and file_id.
1367 ****************************************************************************/
1368
1369 files_struct *file_find_dif(struct smbd_server_connection *sconn,
1370                             struct file_id id, unsigned long gen_id)
1371 {
1372         int count=0;
1373         files_struct *fsp;
1374
1375         if (gen_id == 0) {
1376                 return NULL;
1377         }
1378
1379         for (fsp = sconn->files; fsp; fsp = fsp->next,count++) {
1380                 /*
1381                  * We can have a fsp->fh->fd == -1 here as it could be a stat
1382                  * open.
1383                  */
1384                 if (!file_id_equal(&fsp->file_id, &id)) {
1385                         continue;
1386                 }
1387                 if (!fsp->fsp_flags.is_fsa) {
1388                         continue;
1389                 }
1390                 if (fh_get_gen_id(fsp->fh) != gen_id) {
1391                         continue;
1392                 }
1393                 if (count > 10) {
1394                         DLIST_PROMOTE(sconn->files, fsp);
1395                 }
1396                 /* Paranoia check. */
1397                 if ((fsp_get_pathref_fd(fsp) == -1) &&
1398                     (fsp->oplock_type != NO_OPLOCK &&
1399                      fsp->oplock_type != LEASE_OPLOCK))
1400                 {
1401                         struct file_id_buf idbuf;
1402
1403                         DBG_ERR("file %s file_id = "
1404                                 "%s, gen = %u oplock_type = %u is a "
1405                                 "stat open with oplock type !\n",
1406                                 fsp_str_dbg(fsp),
1407                                 file_id_str_buf(fsp->file_id, &idbuf),
1408                                 (unsigned int)fh_get_gen_id(fsp->fh),
1409                                 (unsigned int)fsp->oplock_type);
1410                         smb_panic("file_find_dif");
1411                 }
1412                 return fsp;
1413         }
1414
1415         return NULL;
1416 }
1417
1418 /****************************************************************************
1419  Find the first fsp given a device and inode.
1420  We use a singleton cache here to speed up searching from getfilepathinfo
1421  calls.
1422 ****************************************************************************/
1423
1424 files_struct *file_find_di_first(struct smbd_server_connection *sconn,
1425                                  struct file_id id,
1426                                  bool need_fsa)
1427 {
1428         files_struct *fsp;
1429
1430         if (file_id_equal(&sconn->fsp_fi_cache.id, &id)) {
1431                 /* Positive or negative cache hit. */
1432                 return sconn->fsp_fi_cache.fsp;
1433         }
1434
1435         sconn->fsp_fi_cache.id = id;
1436
1437         for (fsp=sconn->files;fsp;fsp=fsp->next) {
1438                 if (need_fsa && !fsp->fsp_flags.is_fsa) {
1439                         continue;
1440                 }
1441                 if (file_id_equal(&fsp->file_id, &id)) {
1442                         /* Setup positive cache. */
1443                         sconn->fsp_fi_cache.fsp = fsp;
1444                         return fsp;
1445                 }
1446         }
1447
1448         /* Setup negative cache. */
1449         sconn->fsp_fi_cache.fsp = NULL;
1450         return NULL;
1451 }
1452
1453 /****************************************************************************
1454  Find the next fsp having the same device and inode.
1455 ****************************************************************************/
1456
1457 files_struct *file_find_di_next(files_struct *start_fsp,
1458                                 bool need_fsa)
1459 {
1460         files_struct *fsp;
1461
1462         for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
1463                 if (need_fsa && !fsp->fsp_flags.is_fsa) {
1464                         continue;
1465                 }
1466                 if (file_id_equal(&fsp->file_id, &start_fsp->file_id)) {
1467                         return fsp;
1468                 }
1469         }
1470
1471         return NULL;
1472 }
1473
1474 struct files_struct *file_find_one_fsp_from_lease_key(
1475         struct smbd_server_connection *sconn,
1476         const struct smb2_lease_key *lease_key)
1477 {
1478         struct files_struct *fsp;
1479
1480         for (fsp = sconn->files; fsp; fsp=fsp->next) {
1481                 if ((fsp->lease != NULL) &&
1482                     (fsp->lease->lease.lease_key.data[0] ==
1483                      lease_key->data[0]) &&
1484                     (fsp->lease->lease.lease_key.data[1] ==
1485                      lease_key->data[1])) {
1486                         return fsp;
1487                 }
1488         }
1489         return NULL;
1490 }
1491
1492 /****************************************************************************
1493  Find any fsp open with a pathname below that of an already open path.
1494 ****************************************************************************/
1495
1496 bool file_find_subpath(files_struct *dir_fsp)
1497 {
1498         files_struct *fsp;
1499         size_t dlen;
1500         char *d_fullname = NULL;
1501
1502         d_fullname = talloc_asprintf(talloc_tos(), "%s/%s",
1503                                      dir_fsp->conn->connectpath,
1504                                      dir_fsp->fsp_name->base_name);
1505
1506         if (!d_fullname) {
1507                 return false;
1508         }
1509
1510         dlen = strlen(d_fullname);
1511
1512         for (fsp=dir_fsp->conn->sconn->files; fsp; fsp=fsp->next) {
1513                 char *d1_fullname;
1514
1515                 if (fsp == dir_fsp) {
1516                         continue;
1517                 }
1518
1519                 d1_fullname = talloc_asprintf(talloc_tos(),
1520                                         "%s/%s",
1521                                         fsp->conn->connectpath,
1522                                         fsp->fsp_name->base_name);
1523
1524                 /*
1525                  * If the open file has a path that is a longer
1526                  * component, then it's a subpath.
1527                  */
1528                 if (strnequal(d_fullname, d1_fullname, dlen) &&
1529                                 (d1_fullname[dlen] == '/')) {
1530                         TALLOC_FREE(d1_fullname);
1531                         TALLOC_FREE(d_fullname);
1532                         return true;
1533                 }
1534                 TALLOC_FREE(d1_fullname);
1535         }
1536
1537         TALLOC_FREE(d_fullname);
1538         return false;
1539 }
1540
1541 /****************************************************************************
1542  Free up a fsp.
1543 ****************************************************************************/
1544
1545 static void fsp_free(files_struct *fsp)
1546 {
1547         struct smbd_server_connection *sconn = fsp->conn->sconn;
1548
1549         if (fsp == sconn->fsp_fi_cache.fsp) {
1550                 ZERO_STRUCT(sconn->fsp_fi_cache);
1551         }
1552
1553         DLIST_REMOVE(sconn->files, fsp);
1554         SMB_ASSERT(sconn->num_files > 0);
1555         sconn->num_files--;
1556
1557         TALLOC_FREE(fsp->fake_file_handle);
1558
1559         if (fh_get_refcount(fsp->fh) == 1) {
1560                 TALLOC_FREE(fsp->fh);
1561         } else {
1562                 size_t new_refcount = fh_get_refcount(fsp->fh) - 1;
1563                 fh_set_refcount(fsp->fh, new_refcount);
1564         }
1565
1566         if (fsp->lease != NULL) {
1567                 if (fsp->lease->ref_count == 1) {
1568                         TALLOC_FREE(fsp->lease);
1569                 } else {
1570                         fsp->lease->ref_count--;
1571                 }
1572         }
1573
1574         fsp->conn->num_files_open--;
1575
1576         if (fsp->fsp_name != NULL &&
1577             fsp->fsp_name->fsp_link != NULL)
1578         {
1579                 /*
1580                  * Free fsp_link of fsp->fsp_name. To do this in the correct
1581                  * talloc destructor order we have to do it here. The
1582                  * talloc_free() of the link should set the fsp pointer to NULL.
1583                  */
1584                 TALLOC_FREE(fsp->fsp_name->fsp_link);
1585                 SMB_ASSERT(fsp->fsp_name->fsp == NULL);
1586         }
1587
1588         /* this is paranoia, just in case someone tries to reuse the
1589            information */
1590         ZERO_STRUCTP(fsp);
1591
1592         /* fsp->fsp_name is a talloc child and is free'd automatically. */
1593         TALLOC_FREE(fsp);
1594 }
1595
1596 /*
1597  * Rundown of all smb-related sub-structures of an fsp
1598  */
1599 void fsp_unbind_smb(struct smb_request *req, files_struct *fsp)
1600 {
1601         if (fsp == fsp->conn->cwd_fsp) {
1602                 return;
1603         }
1604
1605         if (fsp->notify) {
1606                 size_t len = fsp_fullbasepath(fsp, NULL, 0);
1607                 char fullpath[len+1];
1608
1609                 fsp_fullbasepath(fsp, fullpath, sizeof(fullpath));
1610
1611                 /*
1612                  * Avoid /. at the end of the path name. notify can't
1613                  * deal with it.
1614                  */
1615                 if (len > 1 && fullpath[len-1] == '.' &&
1616                     fullpath[len-2] == '/') {
1617                         fullpath[len-2] = '\0';
1618                 }
1619
1620                 notify_remove(fsp->conn->sconn->notify_ctx, fsp, fullpath);
1621                 TALLOC_FREE(fsp->notify);
1622         }
1623
1624         /* Ensure this event will never fire. */
1625         TALLOC_FREE(fsp->update_write_time_event);
1626
1627         if (fsp->op != NULL) {
1628                 fsp->op->compat = NULL;
1629         }
1630         TALLOC_FREE(fsp->op);
1631
1632         if ((req != NULL) && (fsp == req->chain_fsp)) {
1633                 req->chain_fsp = NULL;
1634         }
1635
1636         /*
1637          * Clear all possible chained fsp
1638          * pointers in the SMB2 request queue.
1639          */
1640         remove_smb2_chained_fsp(fsp);
1641 }
1642
1643 void file_free(struct smb_request *req, files_struct *fsp)
1644 {
1645         struct smbd_server_connection *sconn = fsp->conn->sconn;
1646         uint64_t fnum = fsp->fnum;
1647
1648         fsp_unbind_smb(req, fsp);
1649
1650         /* Drop all remaining extensions. */
1651         vfs_remove_all_fsp_extensions(fsp);
1652
1653         fsp_free(fsp);
1654
1655         DBG_INFO("freed files structure %"PRIu64" (%zu used)\n",
1656                  fnum,
1657                  sconn->num_files);
1658 }
1659
1660 /****************************************************************************
1661  Get an fsp from a packet given a 16 bit fnum.
1662 ****************************************************************************/
1663
1664 files_struct *file_fsp(struct smb_request *req, uint16_t fid)
1665 {
1666         struct smbXsrv_open *op;
1667         NTSTATUS status;
1668         NTTIME now = 0;
1669         files_struct *fsp;
1670
1671         if (req == NULL) {
1672                 /*
1673                  * We should never get here. req==NULL could in theory
1674                  * only happen from internal opens with a non-zero
1675                  * root_dir_fid. Internal opens just don't do that, at
1676                  * least they are not supposed to do so. And if they
1677                  * start to do so, they better fake up a smb_request
1678                  * from which we get the right smbd_server_conn. While
1679                  * this should never happen, let's return NULL here.
1680                  */
1681                 return NULL;
1682         }
1683
1684         if (req->chain_fsp != NULL) {
1685                 if (req->chain_fsp->fsp_flags.closing) {
1686                         return NULL;
1687                 }
1688                 return req->chain_fsp;
1689         }
1690
1691         if (req->xconn == NULL) {
1692                 return NULL;
1693         }
1694
1695         now = timeval_to_nttime(&req->request_time);
1696
1697         status = smb1srv_open_lookup(req->xconn,
1698                                      fid, now, &op);
1699         if (!NT_STATUS_IS_OK(status)) {
1700                 return NULL;
1701         }
1702
1703         fsp = op->compat;
1704         if (fsp == NULL) {
1705                 return NULL;
1706         }
1707
1708         if (fsp->fsp_flags.closing) {
1709                 return NULL;
1710         }
1711
1712         req->chain_fsp = fsp;
1713         return fsp;
1714 }
1715
1716 struct files_struct *file_fsp_get(struct smbd_smb2_request *smb2req,
1717                                   uint64_t persistent_id,
1718                                   uint64_t volatile_id)
1719 {
1720         struct smbXsrv_open *op;
1721         NTSTATUS status;
1722         NTTIME now = 0;
1723         struct files_struct *fsp;
1724
1725         now = timeval_to_nttime(&smb2req->request_time);
1726
1727         status = smb2srv_open_lookup(smb2req->xconn,
1728                                      persistent_id, volatile_id,
1729                                      now, &op);
1730         if (!NT_STATUS_IS_OK(status)) {
1731                 return NULL;
1732         }
1733
1734         fsp = op->compat;
1735         if (fsp == NULL) {
1736                 return NULL;
1737         }
1738
1739         if (smb2req->tcon == NULL) {
1740                 return NULL;
1741         }
1742
1743         if (smb2req->tcon->compat != fsp->conn) {
1744                 return NULL;
1745         }
1746
1747         if (smb2req->session == NULL) {
1748                 return NULL;
1749         }
1750
1751         if (smb2req->session->global->session_wire_id != fsp->vuid) {
1752                 return NULL;
1753         }
1754
1755         if (fsp->fsp_flags.closing) {
1756                 return NULL;
1757         }
1758
1759         return fsp;
1760 }
1761
1762 struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
1763                                    uint64_t persistent_id,
1764                                    uint64_t volatile_id)
1765 {
1766         struct files_struct *fsp;
1767
1768         if (smb2req->compat_chain_fsp != NULL) {
1769                 if (smb2req->compat_chain_fsp->fsp_flags.closing) {
1770                         return NULL;
1771                 }
1772                 return smb2req->compat_chain_fsp;
1773         }
1774
1775         fsp = file_fsp_get(smb2req, persistent_id, volatile_id);
1776         if (fsp == NULL) {
1777                 return NULL;
1778         }
1779
1780         smb2req->compat_chain_fsp = fsp;
1781         return fsp;
1782 }
1783
1784 /****************************************************************************
1785  Duplicate the file handle part for a DOS or FCB open.
1786 ****************************************************************************/
1787
1788 NTSTATUS dup_file_fsp(
1789         files_struct *from,
1790         uint32_t access_mask,
1791         files_struct *to)
1792 {
1793         size_t new_refcount;
1794
1795         /* this can never happen for print files */
1796         SMB_ASSERT(from->print_file == NULL);
1797
1798         TALLOC_FREE(to->fh);
1799
1800         to->fh = from->fh;
1801         new_refcount = fh_get_refcount(to->fh) + 1;
1802         fh_set_refcount(to->fh, new_refcount);
1803
1804         to->file_id = from->file_id;
1805         to->initial_allocation_size = from->initial_allocation_size;
1806         to->file_pid = from->file_pid;
1807         to->vuid = from->vuid;
1808         to->open_time = from->open_time;
1809         to->access_mask = access_mask;
1810         to->oplock_type = from->oplock_type;
1811         to->fsp_flags.can_lock = from->fsp_flags.can_lock;
1812         to->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1813         to->fsp_flags.can_write =
1814                 CAN_WRITE(from->conn) &&
1815                 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1816         to->fsp_flags.modified = from->fsp_flags.modified;
1817         to->fsp_flags.is_directory = from->fsp_flags.is_directory;
1818         to->fsp_flags.aio_write_behind = from->fsp_flags.aio_write_behind;
1819         to->fsp_flags.is_fsa = from->fsp_flags.is_fsa;
1820         to->fsp_flags.is_pathref = from->fsp_flags.is_pathref;
1821         to->fsp_flags.have_proc_fds = from->fsp_flags.have_proc_fds;
1822         to->fsp_flags.is_dirfsp = from->fsp_flags.is_dirfsp;
1823
1824         return fsp_set_smb_fname(to, from->fsp_name);
1825 }
1826
1827 /**
1828  * Return a jenkins hash of a pathname on a connection.
1829  */
1830
1831 NTSTATUS file_name_hash(connection_struct *conn,
1832                         const char *name, uint32_t *p_name_hash)
1833 {
1834         char tmpbuf[PATH_MAX];
1835         char *fullpath, *to_free;
1836         ssize_t len;
1837         TDB_DATA key;
1838
1839         /* Set the hash of the full pathname. */
1840
1841         if (name[0] == '/') {
1842                 strlcpy(tmpbuf, name, sizeof(tmpbuf));
1843                 fullpath = tmpbuf;
1844                 len = strlen(fullpath);
1845                 to_free = NULL;
1846         } else {
1847                 len = full_path_tos(conn->connectpath,
1848                                     name,
1849                                     tmpbuf,
1850                                     sizeof(tmpbuf),
1851                                     &fullpath,
1852                                     &to_free);
1853         }
1854         if (len == -1) {
1855                 return NT_STATUS_NO_MEMORY;
1856         }
1857         key = (TDB_DATA) { .dptr = (uint8_t *)fullpath, .dsize = len+1 };
1858         *p_name_hash = tdb_jenkins_hash(&key);
1859
1860         DEBUG(10,("file_name_hash: %s hash 0x%x\n",
1861                   fullpath,
1862                 (unsigned int)*p_name_hash ));
1863
1864         TALLOC_FREE(to_free);
1865         return NT_STATUS_OK;
1866 }
1867
1868 static NTSTATUS fsp_attach_smb_fname(struct files_struct *fsp,
1869                                      struct smb_filename **_smb_fname)
1870 {
1871         struct smb_filename *smb_fname_new = talloc_move(fsp, _smb_fname);
1872         const char *name_str = NULL;
1873         uint32_t name_hash = 0;
1874         NTSTATUS status;
1875
1876         name_str = smb_fname_str_dbg(smb_fname_new);
1877         if (name_str == NULL) {
1878                 return NT_STATUS_NO_MEMORY;
1879         }
1880
1881         status = file_name_hash(fsp->conn,
1882                                 name_str,
1883                                 &name_hash);
1884         if (!NT_STATUS_IS_OK(status)) {
1885                 return status;
1886         }
1887
1888         status = fsp_smb_fname_link(fsp,
1889                                     &smb_fname_new->fsp_link,
1890                                     &smb_fname_new->fsp);
1891         if (!NT_STATUS_IS_OK(status)) {
1892                 return status;
1893         }
1894
1895         fsp->name_hash = name_hash;
1896         fsp->fsp_name = smb_fname_new;
1897         *_smb_fname = NULL;
1898         return NT_STATUS_OK;
1899 }
1900
1901 /**
1902  * The only way that the fsp->fsp_name field should ever be set.
1903  */
1904 NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
1905                            const struct smb_filename *smb_fname_in)
1906 {
1907         struct smb_filename *smb_fname_old = fsp->fsp_name;
1908         struct smb_filename *smb_fname_new = NULL;
1909         NTSTATUS status;
1910
1911         smb_fname_new = cp_smb_filename(fsp, smb_fname_in);
1912         if (smb_fname_new == NULL) {
1913                 return NT_STATUS_NO_MEMORY;
1914         }
1915
1916         status = fsp_attach_smb_fname(fsp, &smb_fname_new);
1917         if (!NT_STATUS_IS_OK(status)) {
1918                 TALLOC_FREE(smb_fname_new);
1919                 return status;
1920         }
1921
1922         if (smb_fname_old != NULL) {
1923                 smb_fname_fsp_unlink(smb_fname_old);
1924                 TALLOC_FREE(smb_fname_old);
1925         }
1926
1927         return NT_STATUS_OK;
1928 }
1929
1930 size_t fsp_fullbasepath(struct files_struct *fsp, char *buf, size_t buflen)
1931 {
1932         int len = 0;
1933         char tmp_buf[1] = {'\0'};
1934
1935         /*
1936          * Don't pass NULL buffer to snprintf (to satisfy static checker)
1937          * Some callers will call this function with NULL for buf and
1938          * 0 for buflen in order to get length of fullbasepath (without
1939          * needing to allocate or write to buf)
1940          */
1941         if (buf == NULL) {
1942                 buf = tmp_buf;
1943                 SMB_ASSERT(buflen==0);
1944         }
1945
1946         len = snprintf(buf, buflen, "%s/%s", fsp->conn->connectpath,
1947                        fsp->fsp_name->base_name);
1948         SMB_ASSERT(len>0);
1949
1950         return len;
1951 }
1952
1953 void fsp_set_base_fsp(struct files_struct *fsp, struct files_struct *base_fsp)
1954 {
1955         SMB_ASSERT(fsp->stream_fsp == NULL);
1956         if (base_fsp != NULL) {
1957                 SMB_ASSERT(base_fsp->base_fsp == NULL);
1958                 SMB_ASSERT(base_fsp->stream_fsp == NULL);
1959         }
1960
1961         if (fsp->base_fsp != NULL) {
1962                 SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
1963                 fsp->base_fsp->stream_fsp = NULL;
1964         }
1965
1966         fsp->base_fsp = base_fsp;
1967         if (fsp->base_fsp != NULL) {
1968                 fsp->base_fsp->stream_fsp = fsp;
1969         }
1970 }
1971
1972 bool fsp_is_alternate_stream(const struct files_struct *fsp)
1973 {
1974         return (fsp->base_fsp != NULL);
1975 }
1976
1977 struct files_struct *metadata_fsp(struct files_struct *fsp)
1978 {
1979         if (fsp_is_alternate_stream(fsp)) {
1980                 return fsp->base_fsp;
1981         }
1982         return fsp;
1983 }