Line data Source code
1 : /*
2 : Unix SMB/Netbios implementation.
3 : Version 1.9.
4 : VFS initialisation and support functions
5 : Copyright (C) Tim Potter 1999
6 : Copyright (C) Alexander Bokovoy 2002
7 : Copyright (C) James Peach 2006
8 : Copyright (C) Volker Lendecke 2009
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 :
23 : This work was sponsored by Optifacio Software Services, Inc.
24 : */
25 :
26 : #include "includes.h"
27 : #include "system/filesys.h"
28 : #include "smbd/smbd.h"
29 : #include "smbd/globals.h"
30 : #include "../lib/util/memcache.h"
31 : #include "transfer_file.h"
32 : #include "ntioctl.h"
33 : #include "lib/util/tevent_unix.h"
34 : #include "lib/util/tevent_ntstatus.h"
35 : #include "lib/util/sys_rw.h"
36 :
37 : #undef DBGC_CLASS
38 : #define DBGC_CLASS DBGC_VFS
39 :
40 : static_decl_vfs;
41 :
42 : struct vfs_fsp_data {
43 : struct vfs_fsp_data *next;
44 : struct vfs_handle_struct *owner;
45 : void (*destroy)(void *p_data);
46 : void *_dummy_;
47 : /* NOTE: This structure contains four pointers so that we can guarantee
48 : * that the end of the structure is always both 4-byte and 8-byte aligned.
49 : */
50 : };
51 :
52 : struct vfs_init_function_entry {
53 : char *name;
54 : struct vfs_init_function_entry *prev, *next;
55 : const struct vfs_fn_pointers *fns;
56 : };
57 :
58 : /****************************************************************************
59 : maintain the list of available backends
60 : ****************************************************************************/
61 :
62 758638 : static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
63 : {
64 758638 : struct vfs_init_function_entry *entry = backends;
65 :
66 758638 : DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
67 :
68 3335749 : while(entry) {
69 2934865 : if (strcmp(entry->name, name)==0) return entry;
70 2577111 : entry = entry->next;
71 : }
72 :
73 391928 : return NULL;
74 : }
75 :
76 248908 : NTSTATUS smb_register_vfs(int version, const char *name,
77 : const struct vfs_fn_pointers *fns)
78 : {
79 248908 : struct vfs_init_function_entry *entry = backends;
80 :
81 248908 : if ((version != SMB_VFS_INTERFACE_VERSION)) {
82 0 : DEBUG(0, ("Failed to register vfs module.\n"
83 : "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
84 : "current SMB_VFS_INTERFACE_VERSION is %d.\n"
85 : "Please recompile against the current Samba Version!\n",
86 : version, SMB_VFS_INTERFACE_VERSION));
87 0 : return NT_STATUS_OBJECT_TYPE_MISMATCH;
88 : }
89 :
90 248908 : if (!name || !name[0]) {
91 0 : DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
92 0 : return NT_STATUS_INVALID_PARAMETER;
93 : }
94 :
95 248908 : if (vfs_find_backend_entry(name)) {
96 0 : DEBUG(0,("VFS module %s already loaded!\n", name));
97 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
98 : }
99 :
100 248908 : entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
101 248908 : entry->name = smb_xstrdup(name);
102 248908 : entry->fns = fns;
103 :
104 248908 : DLIST_ADD(backends, entry);
105 248908 : DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
106 248908 : return NT_STATUS_OK;
107 : }
108 :
109 : /****************************************************************************
110 : initialise default vfs hooks
111 : ****************************************************************************/
112 :
113 55526 : static void vfs_init_default(connection_struct *conn)
114 : {
115 55526 : DEBUG(3, ("Initialising default vfs hooks\n"));
116 55526 : vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
117 55526 : }
118 :
119 : /****************************************************************************
120 : initialise custom vfs hooks
121 : ****************************************************************************/
122 :
123 357754 : bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
124 : {
125 357754 : char *module_path = NULL;
126 357754 : char *module_name = NULL;
127 357754 : char *module_param = NULL, *p;
128 5129 : vfs_handle_struct *handle;
129 5129 : const struct vfs_init_function_entry *entry;
130 :
131 357754 : if (!conn||!vfs_object||!vfs_object[0]) {
132 0 : DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
133 : "empty vfs_object!\n"));
134 0 : return False;
135 : }
136 :
137 357754 : if(!backends) {
138 28497 : static_init_vfs(NULL);
139 : }
140 :
141 357754 : DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
142 :
143 357754 : module_path = smb_xstrdup(vfs_object);
144 :
145 357754 : p = strchr_m(module_path, ':');
146 :
147 357754 : if (p) {
148 0 : *p = 0;
149 0 : module_param = p+1;
150 0 : trim_char(module_param, ' ', ' ');
151 : }
152 :
153 357754 : trim_char(module_path, ' ', ' ');
154 :
155 357754 : module_name = smb_xstrdup(module_path);
156 :
157 357754 : if ((module_name[0] == '/') &&
158 55526 : (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
159 :
160 : /*
161 : * Extract the module name from the path. Just use the base
162 : * name of the last path component.
163 : */
164 :
165 0 : SAFE_FREE(module_name);
166 0 : module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
167 :
168 0 : p = strchr_m(module_name, '.');
169 :
170 0 : if (p != NULL) {
171 0 : *p = '\0';
172 : }
173 : }
174 :
175 : /* First, try to load the module with the new module system */
176 357754 : entry = vfs_find_backend_entry(module_name);
177 357754 : if (!entry) {
178 2984 : NTSTATUS status;
179 :
180 151976 : DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
181 : vfs_object));
182 :
183 151976 : status = smb_load_module("vfs", module_path);
184 151976 : if (!NT_STATUS_IS_OK(status)) {
185 0 : DEBUG(0, ("error probing vfs module '%s': %s\n",
186 : module_path, nt_errstr(status)));
187 0 : goto fail;
188 : }
189 :
190 151976 : entry = vfs_find_backend_entry(module_name);
191 151976 : if (!entry) {
192 0 : DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
193 0 : goto fail;
194 : }
195 : }
196 :
197 357754 : DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
198 :
199 357754 : handle = talloc_zero(conn, vfs_handle_struct);
200 357754 : if (!handle) {
201 0 : DEBUG(0,("TALLOC_ZERO() failed!\n"));
202 0 : goto fail;
203 : }
204 357754 : handle->conn = conn;
205 357754 : handle->fns = entry->fns;
206 357754 : if (module_param) {
207 0 : handle->param = talloc_strdup(conn, module_param);
208 : }
209 357754 : DLIST_ADD(conn->vfs_handles, handle);
210 :
211 357754 : SAFE_FREE(module_path);
212 357754 : SAFE_FREE(module_name);
213 352625 : return True;
214 :
215 0 : fail:
216 0 : SAFE_FREE(module_path);
217 0 : SAFE_FREE(module_name);
218 0 : return False;
219 : }
220 :
221 : /*****************************************************************
222 : Allow VFS modules to extend files_struct with VFS-specific state.
223 : This will be ok for small numbers of extensions, but might need to
224 : be refactored if it becomes more widely used.
225 : ******************************************************************/
226 :
227 : #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
228 :
229 232278 : void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
230 : files_struct *fsp, size_t ext_size,
231 : void (*destroy_fn)(void *p_data))
232 : {
233 431 : struct vfs_fsp_data *ext;
234 431 : void * ext_data;
235 :
236 : /* Prevent VFS modules adding multiple extensions. */
237 232278 : if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
238 1490 : return ext_data;
239 : }
240 :
241 230788 : ext = talloc_zero_size(
242 : handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
243 230788 : if (ext == NULL) {
244 0 : return NULL;
245 : }
246 :
247 230788 : ext->owner = handle;
248 230788 : ext->next = fsp->vfs_extension;
249 230788 : ext->destroy = destroy_fn;
250 230788 : fsp->vfs_extension = ext;
251 230788 : return EXT_DATA_AREA(ext);
252 : }
253 :
254 167742 : void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
255 : {
256 431 : struct vfs_fsp_data *curr;
257 431 : struct vfs_fsp_data *prev;
258 :
259 167742 : for (curr = fsp->vfs_extension, prev = NULL;
260 168156 : curr;
261 414 : prev = curr, curr = curr->next) {
262 168156 : if (curr->owner == handle) {
263 167742 : if (prev) {
264 414 : prev->next = curr->next;
265 : } else {
266 167328 : fsp->vfs_extension = curr->next;
267 : }
268 167742 : if (curr->destroy) {
269 1464 : curr->destroy(EXT_DATA_AREA(curr));
270 : }
271 167742 : TALLOC_FREE(curr);
272 167742 : return;
273 : }
274 : }
275 : }
276 :
277 6256651 : void vfs_remove_all_fsp_extensions(files_struct *fsp)
278 : {
279 32284 : struct vfs_fsp_data *curr;
280 32284 : struct vfs_fsp_data *next;
281 :
282 6319645 : for (curr = fsp->vfs_extension; curr; curr = next) {
283 :
284 62994 : next = curr->next;
285 62994 : fsp->vfs_extension = next;
286 :
287 62994 : if (curr->destroy) {
288 4676 : curr->destroy(EXT_DATA_AREA(curr));
289 : }
290 62994 : TALLOC_FREE(curr);
291 : }
292 6256651 : }
293 :
294 901654 : void *vfs_memctx_fsp_extension(vfs_handle_struct *handle,
295 : const struct files_struct *fsp)
296 : {
297 946 : struct vfs_fsp_data *head;
298 :
299 1096836 : for (head = fsp->vfs_extension; head; head = head->next) {
300 541569 : if (head->owner == handle) {
301 346387 : return head;
302 : }
303 : }
304 :
305 554832 : return NULL;
306 : }
307 :
308 831382 : void *vfs_fetch_fsp_extension(vfs_handle_struct *handle,
309 : const struct files_struct *fsp)
310 : {
311 946 : struct vfs_fsp_data *head;
312 :
313 831382 : head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
314 831382 : if (head != NULL) {
315 276115 : return EXT_DATA_AREA(head);
316 : }
317 :
318 554832 : return NULL;
319 : }
320 :
321 : #undef EXT_DATA_AREA
322 :
323 : /*
324 : * Ensure this module catches all VFS functions.
325 : */
326 : #ifdef DEVELOPER
327 94178 : void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
328 : const char *module)
329 : {
330 94178 : bool missing_fn = false;
331 1494 : unsigned int idx;
332 94178 : const uintptr_t *end = (const uintptr_t *)(fns + 1);
333 :
334 9323622 : for (idx = 0; ((const uintptr_t *)fns + idx) < end; idx++) {
335 9229444 : if (*((const uintptr_t *)fns + idx) == 0) {
336 0 : DBG_ERR("VFS function at index %d not implemented "
337 : "in module %s\n", idx, module);
338 0 : missing_fn = true;
339 : }
340 : }
341 :
342 94178 : if (missing_fn) {
343 0 : smb_panic("Required VFS function not implemented in module.\n");
344 : }
345 94178 : }
346 : #else
347 : void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
348 : const char *module)
349 : {
350 : }
351 : #endif
352 :
353 : /*****************************************************************
354 : Generic VFS init.
355 : ******************************************************************/
356 :
357 55526 : bool smbd_vfs_init(connection_struct *conn)
358 : {
359 874 : const char **vfs_objects;
360 55526 : unsigned int i = 0;
361 55526 : int j = 0;
362 :
363 : /* Normal share - initialise with disk access functions */
364 55526 : vfs_init_default(conn);
365 :
366 : /* No need to load vfs modules for printer connections */
367 55526 : if (conn->printer) {
368 28 : return True;
369 : }
370 :
371 55498 : if (lp_widelinks(SNUM(conn))) {
372 : /*
373 : * As the widelinks logic is now moving into a
374 : * vfs_widelinks module, we need to custom load
375 : * it after the default module is initialized.
376 : * That way no changes to smb.conf files are
377 : * needed.
378 : */
379 230 : bool ok = vfs_init_custom(conn, "widelinks");
380 230 : if (!ok) {
381 0 : DBG_ERR("widelinks enabled and vfs_init_custom "
382 : "failed for vfs_widelinks module\n");
383 0 : return false;
384 : }
385 : }
386 :
387 55498 : vfs_objects = lp_vfs_objects(SNUM(conn));
388 :
389 : /* Override VFS functions if 'vfs object' was not specified*/
390 55498 : if (!vfs_objects || !vfs_objects[0])
391 39 : return True;
392 :
393 357455 : for (i=0; vfs_objects[i] ;) {
394 301996 : i++;
395 : }
396 :
397 357455 : for (j=i-1; j >= 0; j--) {
398 301996 : if (!vfs_init_custom(conn, vfs_objects[j])) {
399 0 : DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
400 0 : return False;
401 : }
402 : }
403 54585 : return True;
404 : }
405 :
406 : /*******************************************************************
407 : Check if a file exists in the vfs.
408 : ********************************************************************/
409 :
410 16 : NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
411 : {
412 : /* Only return OK if stat was successful and S_ISREG */
413 16 : if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
414 16 : S_ISREG(smb_fname->st.st_ex_mode)) {
415 16 : return NT_STATUS_OK;
416 : }
417 :
418 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
419 : }
420 :
421 17044 : bool vfs_valid_pread_range(off_t offset, size_t length)
422 : {
423 17044 : return sys_valid_io_range(offset, length);
424 : }
425 :
426 193062 : bool vfs_valid_pwrite_range(off_t offset, size_t length)
427 : {
428 : /*
429 : * See MAXFILESIZE in [MS-FSA] 2.1.5.3 Server Requests a Write
430 : */
431 113 : static const uint64_t maxfilesize = 0xfffffff0000;
432 113 : uint64_t last_byte_ofs;
433 113 : bool ok;
434 :
435 193062 : ok = sys_valid_io_range(offset, length);
436 193062 : if (!ok) {
437 36 : return false;
438 : }
439 :
440 193026 : if (length == 0) {
441 663 : return true;
442 : }
443 :
444 192326 : last_byte_ofs = offset + length;
445 192326 : if (last_byte_ofs > maxfilesize) {
446 6 : return false;
447 : }
448 :
449 192244 : return true;
450 : }
451 :
452 3336 : ssize_t vfs_pwrite_data(struct smb_request *req,
453 : files_struct *fsp,
454 : const char *buffer,
455 : size_t N,
456 : off_t offset)
457 : {
458 3336 : size_t total=0;
459 12 : ssize_t ret;
460 12 : bool ok;
461 :
462 3336 : ok = vfs_valid_pwrite_range(offset, N);
463 3336 : if (!ok) {
464 0 : errno = EINVAL;
465 0 : return -1;
466 : }
467 :
468 3336 : if (req && req->unread_bytes) {
469 0 : int sockfd = req->xconn->transport.sock;
470 0 : SMB_ASSERT(req->unread_bytes == N);
471 : /* VFS_RECVFILE must drain the socket
472 : * before returning. */
473 0 : req->unread_bytes = 0;
474 : /*
475 : * Leave the socket non-blocking and
476 : * use SMB_VFS_RECVFILE. If it returns
477 : * EAGAIN || EWOULDBLOCK temporarily set
478 : * the socket blocking and retry
479 : * the RECVFILE.
480 : */
481 0 : while (total < N) {
482 0 : ret = SMB_VFS_RECVFILE(sockfd,
483 : fsp,
484 : offset + total,
485 : N - total);
486 0 : if (ret == 0 || (ret == -1 &&
487 0 : (errno == EAGAIN ||
488 0 : errno == EWOULDBLOCK))) {
489 0 : int old_flags;
490 : /* Ensure the socket is blocking. */
491 0 : old_flags = fcntl(sockfd, F_GETFL, 0);
492 0 : if (set_blocking(sockfd, true) == -1) {
493 0 : return (ssize_t)-1;
494 : }
495 0 : ret = SMB_VFS_RECVFILE(sockfd,
496 : fsp,
497 : offset + total,
498 : N - total);
499 0 : if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
500 0 : return (ssize_t)-1;
501 : }
502 0 : if (ret == -1) {
503 0 : return (ssize_t)-1;
504 : }
505 0 : total += ret;
506 0 : return (ssize_t)total;
507 : }
508 : /* Any other error case. */
509 0 : if (ret == -1) {
510 0 : return ret;
511 : }
512 0 : total += ret;
513 : }
514 0 : return (ssize_t)total;
515 : }
516 :
517 4468 : while (total < N) {
518 3336 : ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
519 : offset + total);
520 :
521 3336 : if (ret == -1)
522 2204 : return -1;
523 1132 : if (ret == 0)
524 0 : return total;
525 :
526 1132 : total += ret;
527 : }
528 1132 : return (ssize_t)total;
529 : }
530 : /****************************************************************************
531 : An allocate file space call using the vfs interface.
532 : Allocates space for a file from a filedescriptor.
533 : Returns 0 on success, -1 on failure.
534 : ****************************************************************************/
535 :
536 286 : int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
537 : {
538 25 : int ret;
539 286 : connection_struct *conn = fsp->conn;
540 25 : uint64_t space_avail;
541 25 : uint64_t bsize,dfree,dsize;
542 25 : NTSTATUS status;
543 25 : bool ok;
544 :
545 : /*
546 : * Actually try and commit the space on disk....
547 : */
548 :
549 286 : DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
550 : fsp_str_dbg(fsp), (double)len));
551 :
552 286 : ok = vfs_valid_pwrite_range((off_t)len, 0);
553 286 : if (!ok) {
554 0 : DEBUG(0,("vfs_allocate_file_space: %s negative/invalid len "
555 : "requested.\n", fsp_str_dbg(fsp)));
556 0 : errno = EINVAL;
557 0 : return -1;
558 : }
559 :
560 286 : status = vfs_stat_fsp(fsp);
561 286 : if (!NT_STATUS_IS_OK(status)) {
562 0 : return -1;
563 : }
564 :
565 286 : if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
566 44 : return 0;
567 :
568 241 : if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
569 : /* Shrink - use ftruncate. */
570 :
571 6 : DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
572 : "size %.0f\n", fsp_str_dbg(fsp),
573 : (double)fsp->fsp_name->st.st_ex_size));
574 :
575 6 : contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
576 :
577 6 : ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len);
578 :
579 6 : contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
580 :
581 6 : return ret;
582 : }
583 :
584 : /* Grow - we need to test if we have enough space. */
585 :
586 235 : contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
587 :
588 235 : if (lp_strict_allocate(SNUM(fsp->conn))) {
589 : /* See if we have a syscall that will allocate beyond
590 : end-of-file without changing EOF. */
591 0 : ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
592 : 0, len);
593 : } else {
594 211 : ret = 0;
595 : }
596 :
597 235 : contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
598 :
599 235 : if (ret == 0) {
600 : /* We changed the allocation size on disk, but not
601 : EOF - exactly as required. We're done ! */
602 211 : return 0;
603 : }
604 :
605 0 : if (ret == -1 && errno == ENOSPC) {
606 0 : return -1;
607 : }
608 :
609 0 : len -= fsp->fsp_name->st.st_ex_size;
610 0 : len /= 1024; /* Len is now number of 1k blocks needed. */
611 0 : space_avail =
612 0 : get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
613 0 : if (space_avail == (uint64_t)-1) {
614 0 : return -1;
615 : }
616 :
617 0 : DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
618 : "needed blocks = %.0f, space avail = %.0f\n",
619 : fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
620 : (double)space_avail));
621 :
622 0 : if (len > space_avail) {
623 0 : errno = ENOSPC;
624 0 : return -1;
625 : }
626 :
627 0 : return 0;
628 : }
629 :
630 : /****************************************************************************
631 : A vfs set_filelen call.
632 : set the length of a file from a filedescriptor.
633 : Returns 0 on success, -1 on failure.
634 : ****************************************************************************/
635 :
636 392 : int vfs_set_filelen(files_struct *fsp, off_t len)
637 : {
638 10 : int ret;
639 10 : bool ok;
640 :
641 392 : ok = vfs_valid_pwrite_range(len, 0);
642 392 : if (!ok) {
643 0 : errno = EINVAL;
644 0 : return -1;
645 : }
646 :
647 392 : contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
648 :
649 392 : DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
650 : fsp_str_dbg(fsp), (double)len));
651 392 : if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
652 384 : notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
653 : FILE_NOTIFY_CHANGE_SIZE
654 : | FILE_NOTIFY_CHANGE_ATTRIBUTES,
655 384 : fsp->fsp_name->base_name);
656 : }
657 :
658 392 : contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
659 :
660 392 : return ret;
661 : }
662 :
663 : /****************************************************************************
664 : A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
665 : fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
666 : as this is also called from the default SMB_VFS_FTRUNCATE code.
667 : Always extends the file size.
668 : Returns 0 on success, -1 on failure.
669 : ****************************************************************************/
670 :
671 : #define SPARSE_BUF_WRITE_SIZE (32*1024)
672 :
673 0 : int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
674 : {
675 0 : ssize_t pwrite_ret;
676 0 : size_t total = 0;
677 0 : bool ok;
678 :
679 0 : ok = vfs_valid_pwrite_range(offset, len);
680 0 : if (!ok) {
681 0 : errno = EINVAL;
682 0 : return -1;
683 : }
684 :
685 0 : if (!sparse_buf) {
686 0 : sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
687 0 : if (!sparse_buf) {
688 0 : errno = ENOMEM;
689 0 : return -1;
690 : }
691 : }
692 :
693 0 : while (total < len) {
694 0 : size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
695 :
696 0 : pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
697 0 : if (pwrite_ret == -1) {
698 0 : int saved_errno = errno;
699 0 : DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
700 : "%s failed with error %s\n",
701 : fsp_str_dbg(fsp), strerror(saved_errno)));
702 0 : errno = saved_errno;
703 0 : return -1;
704 : }
705 0 : total += pwrite_ret;
706 : }
707 :
708 0 : return 0;
709 : }
710 :
711 : /****************************************************************************
712 : A vfs fill sparse call.
713 : Writes zeros from the end of file to len, if len is greater than EOF.
714 : Used only by strict_sync.
715 : Returns 0 on success, -1 on failure.
716 : ****************************************************************************/
717 :
718 0 : int vfs_fill_sparse(files_struct *fsp, off_t len)
719 : {
720 0 : int ret;
721 0 : NTSTATUS status;
722 0 : off_t offset;
723 0 : size_t num_to_write;
724 0 : bool ok;
725 :
726 0 : ok = vfs_valid_pwrite_range(len, 0);
727 0 : if (!ok) {
728 0 : errno = EINVAL;
729 0 : return -1;
730 : }
731 :
732 0 : status = vfs_stat_fsp(fsp);
733 0 : if (!NT_STATUS_IS_OK(status)) {
734 0 : return -1;
735 : }
736 :
737 0 : if (len <= fsp->fsp_name->st.st_ex_size) {
738 0 : return 0;
739 : }
740 :
741 : #ifdef S_ISFIFO
742 0 : if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
743 0 : return 0;
744 : }
745 : #endif
746 :
747 0 : DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
748 : "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
749 : (double)fsp->fsp_name->st.st_ex_size, (double)len,
750 : (double)(len - fsp->fsp_name->st.st_ex_size)));
751 :
752 0 : contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
753 :
754 0 : offset = fsp->fsp_name->st.st_ex_size;
755 0 : num_to_write = len - fsp->fsp_name->st.st_ex_size;
756 :
757 : /* Only do this on non-stream file handles. */
758 0 : if (!fsp_is_alternate_stream(fsp)) {
759 : /* for allocation try fallocate first. This can fail on some
760 : * platforms e.g. when the filesystem doesn't support it and no
761 : * emulation is being done by the libc (like on AIX with JFS1). In that
762 : * case we do our own emulation. fallocate implementations can
763 : * return ENOTSUP or EINVAL in cases like that. */
764 0 : ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
765 0 : if (ret == -1 && errno == ENOSPC) {
766 0 : goto out;
767 : }
768 0 : if (ret == 0) {
769 0 : goto out;
770 : }
771 0 : DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
772 : "error %d. Falling back to slow manual allocation\n", ret));
773 : }
774 :
775 0 : ret = vfs_slow_fallocate(fsp, offset, num_to_write);
776 :
777 0 : out:
778 :
779 0 : contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
780 0 : return ret;
781 : }
782 :
783 : /*******************************************************************************
784 : Set a fd into blocking/nonblocking mode through VFS
785 : *******************************************************************************/
786 :
787 191068 : int vfs_set_blocking(files_struct *fsp, bool set)
788 : {
789 449 : int val;
790 : #ifdef O_NONBLOCK
791 : #define FLAG_TO_SET O_NONBLOCK
792 : #else
793 : #ifdef SYSV
794 : #define FLAG_TO_SET O_NDELAY
795 : #else /* BSD */
796 : #define FLAG_TO_SET FNDELAY
797 : #endif
798 : #endif
799 :
800 191068 : if (fsp->fsp_flags.is_pathref) {
801 0 : return 0;
802 : }
803 :
804 191068 : val = SMB_VFS_FCNTL(fsp, F_GETFL, 0);
805 191068 : if (val == -1) {
806 0 : return -1;
807 : }
808 :
809 191068 : if (set) {
810 191068 : val &= ~FLAG_TO_SET;
811 : } else {
812 0 : val |= FLAG_TO_SET;
813 : }
814 :
815 191068 : return SMB_VFS_FCNTL(fsp, F_SETFL, val);
816 : #undef FLAG_TO_SET
817 : }
818 :
819 : /****************************************************************************
820 : Transfer some data (n bytes) between two file_struct's.
821 : ****************************************************************************/
822 :
823 26 : static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
824 : {
825 26 : struct files_struct *fsp = (struct files_struct *)file;
826 :
827 26 : return SMB_VFS_PREAD(fsp, buf, len, offset);
828 : }
829 :
830 26 : static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
831 : {
832 26 : struct files_struct *fsp = (struct files_struct *)file;
833 :
834 26 : return SMB_VFS_PWRITE(fsp, buf, len, offset);
835 : }
836 :
837 26 : off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
838 : {
839 26 : return transfer_file_internal((void *)in, (void *)out, n,
840 : vfs_pread_fn, vfs_pwrite_fn);
841 : }
842 :
843 : /*******************************************************************
844 : A vfs_readdir wrapper which just returns the file name.
845 : ********************************************************************/
846 :
847 161114808 : const char *vfs_readdirname(connection_struct *conn,
848 : struct files_struct *dirfsp,
849 : void *p,
850 : char **talloced)
851 : {
852 161114808 : struct dirent *ptr= NULL;
853 7202 : const char *dname;
854 7202 : char *translated;
855 7202 : NTSTATUS status;
856 :
857 161114808 : if (!p)
858 0 : return(NULL);
859 :
860 161114808 : ptr = SMB_VFS_READDIR(conn, dirfsp, (DIR *)p);
861 161114808 : if (!ptr)
862 305193 : return(NULL);
863 :
864 160808579 : dname = ptr->d_name;
865 :
866 160808579 : status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
867 : talloc_tos(), &translated);
868 160808579 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
869 160769059 : *talloced = NULL;
870 160769059 : return dname;
871 : }
872 39520 : *talloced = translated;
873 39520 : if (!NT_STATUS_IS_OK(status)) {
874 0 : return NULL;
875 : }
876 39520 : return translated;
877 : }
878 :
879 : /*******************************************************************
880 : A wrapper for vfs_chdir().
881 : ********************************************************************/
882 :
883 3157872 : int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
884 : {
885 18836 : int ret;
886 3157872 : struct smb_filename *cwd = NULL;
887 :
888 3157872 : if (!LastDir) {
889 968698 : LastDir = SMB_STRDUP("");
890 : }
891 :
892 3157872 : if (ISDOT(smb_fname->base_name)) {
893 : /*
894 : * passing a '.' is a noop,
895 : * and we only expect this after
896 : * everything is initialized.
897 : *
898 : * So the first vfs_ChDir() on a given
899 : * connection_struct must not be '.'.
900 : *
901 : * Note: conn_new() sets
902 : * conn->cwd_fsp->fh->fd = -1
903 : * and vfs_ChDir() leaves with
904 : * conn->cwd_fsp->fh->fd = AT_FDCWD
905 : * on success!
906 : */
907 0 : if (fsp_get_pathref_fd(conn->cwd_fsp) != AT_FDCWD) {
908 : /*
909 : * This should never happen and
910 : * we might change this to
911 : * SMB_ASSERT() in future.
912 : */
913 0 : DBG_ERR("Called with '.' as first operation!\n");
914 0 : log_stack_trace();
915 0 : errno = EINVAL;
916 0 : return -1;
917 : }
918 0 : return 0;
919 : }
920 :
921 5995475 : if (smb_fname->base_name[0] == '/' &&
922 2837603 : strcsequal(LastDir,smb_fname->base_name))
923 : {
924 : /*
925 : * conn->cwd_fsp->fsp_name and the kernel
926 : * are already correct, but conn->cwd_fsp->fh->fd
927 : * might still be -1 as initialized in conn_new().
928 : *
929 : * This can happen when a client made a 2nd
930 : * tree connect to a share with the same underlying
931 : * path (may or may not the same share).
932 : */
933 1367651 : fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
934 1367651 : return 0;
935 : }
936 :
937 1790221 : DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
938 :
939 1790221 : ret = SMB_VFS_CHDIR(conn, smb_fname);
940 1790221 : if (ret != 0) {
941 16363 : return -1;
942 : }
943 :
944 : /*
945 : * Always replace conn->cwd_fsp. We
946 : * don't know if it's been modified by
947 : * VFS modules in the stack.
948 : */
949 1773841 : fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
950 :
951 : /* conn cache. */
952 1773841 : cwd = vfs_GetWd(conn, conn);
953 1773841 : if (cwd == NULL) {
954 : /*
955 : * vfs_GetWd() failed.
956 : * We must be able to read cwd.
957 : * Return to original directory
958 : * and return -1.
959 : */
960 0 : int saved_errno = errno;
961 :
962 0 : if (conn->cwd_fsp->fsp_name == NULL) {
963 : /*
964 : * Failed on the very first chdir()+getwd()
965 : * for this connection. We can't
966 : * continue.
967 : */
968 0 : smb_panic("conn->cwd getwd failed\n");
969 : /* NOTREACHED */
970 : return -1;
971 : }
972 :
973 : /* Return to the previous $cwd. */
974 0 : ret = SMB_VFS_CHDIR(conn, conn->cwd_fsp->fsp_name);
975 0 : if (ret != 0) {
976 0 : smb_panic("conn->cwd getwd failed\n");
977 : /* NOTREACHED */
978 : return -1;
979 : }
980 0 : errno = saved_errno;
981 : /* And fail the chdir(). */
982 0 : return -1;
983 : }
984 :
985 : /* vfs_GetWd() succeeded. */
986 : /* Replace global cache. */
987 1773841 : SAFE_FREE(LastDir);
988 1773841 : LastDir = SMB_STRDUP(smb_fname->base_name);
989 :
990 : /*
991 : * (Indirect) Callers of vfs_ChDir() may still hold references to the
992 : * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
993 : * callers can use it for the lifetime of the SMB request.
994 : */
995 1773841 : talloc_move(talloc_tos(), &conn->cwd_fsp->fsp_name);
996 :
997 1773841 : conn->cwd_fsp->fsp_name = talloc_move(conn->cwd_fsp, &cwd);
998 :
999 1773841 : DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn->cwd_fsp));
1000 :
1001 1769512 : return ret;
1002 : }
1003 :
1004 : /*******************************************************************
1005 : Return the absolute current directory path - given a UNIX pathname.
1006 : Note that this path is returned in DOS format, not UNIX
1007 : format. Note this can be called with conn == NULL.
1008 : ********************************************************************/
1009 :
1010 2400439 : struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
1011 : {
1012 2400439 : struct smb_filename *current_dir_fname = NULL;
1013 4592 : struct file_id key;
1014 2400439 : struct smb_filename *smb_fname_dot = NULL;
1015 2400439 : struct smb_filename *smb_fname_full = NULL;
1016 2400439 : struct smb_filename *result = NULL;
1017 :
1018 2400439 : if (!lp_getwd_cache()) {
1019 0 : goto nocache;
1020 : }
1021 :
1022 2400439 : smb_fname_dot = synthetic_smb_fname(ctx,
1023 : ".",
1024 : NULL,
1025 : NULL,
1026 : 0,
1027 : 0);
1028 2400439 : if (smb_fname_dot == NULL) {
1029 0 : errno = ENOMEM;
1030 0 : goto out;
1031 : }
1032 :
1033 2400439 : if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
1034 : /*
1035 : * Known to fail for root: the directory may be NFS-mounted
1036 : * and exported with root_squash (so has no root access).
1037 : */
1038 0 : DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
1039 : "(NFS problem ?)\n", strerror(errno) ));
1040 0 : goto nocache;
1041 : }
1042 :
1043 2400439 : key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1044 :
1045 2400439 : smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
1046 : smbd_memcache(),
1047 : GETWD_CACHE,
1048 : data_blob_const(&key, sizeof(key)));
1049 :
1050 2400439 : if (smb_fname_full == NULL) {
1051 75028 : goto nocache;
1052 : }
1053 :
1054 2325411 : if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
1055 2325227 : (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
1056 2325227 : (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
1057 2325227 : (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
1058 : /*
1059 : * Ok, we're done
1060 : * Note: smb_fname_full is owned by smbd_memcache()
1061 : * so we must make a copy to return.
1062 : */
1063 2325227 : result = cp_smb_filename(ctx, smb_fname_full);
1064 2325227 : if (result == NULL) {
1065 0 : errno = ENOMEM;
1066 : }
1067 2325227 : goto out;
1068 : }
1069 :
1070 184 : nocache:
1071 :
1072 : /*
1073 : * We don't have the information to hand so rely on traditional
1074 : * methods. The very slow getcwd, which spawns a process on some
1075 : * systems, or the not quite so bad getwd.
1076 : */
1077 :
1078 75212 : current_dir_fname = SMB_VFS_GETWD(conn, ctx);
1079 75212 : if (current_dir_fname == NULL) {
1080 0 : DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1081 : strerror(errno)));
1082 0 : goto out;
1083 : }
1084 :
1085 75212 : if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
1086 75212 : key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1087 :
1088 : /*
1089 : * smbd_memcache() will own current_dir_fname after the
1090 : * memcache_add_talloc call, so we must make
1091 : * a copy on ctx to return.
1092 : */
1093 75212 : result = cp_smb_filename(ctx, current_dir_fname);
1094 75212 : if (result == NULL) {
1095 0 : errno = ENOMEM;
1096 : }
1097 :
1098 : /*
1099 : * Ensure the memory going into the cache
1100 : * doesn't have a destructor so it can be
1101 : * cleanly freed.
1102 : */
1103 75212 : talloc_set_destructor(current_dir_fname, NULL);
1104 :
1105 75212 : memcache_add_talloc(smbd_memcache(),
1106 : GETWD_CACHE,
1107 : data_blob_const(&key, sizeof(key)),
1108 : ¤t_dir_fname);
1109 : /* current_dir_fname is now == NULL here. */
1110 : } else {
1111 : /* current_dir_fname is already allocated on ctx. */
1112 0 : result = current_dir_fname;
1113 : }
1114 :
1115 2400439 : out:
1116 2400439 : TALLOC_FREE(smb_fname_dot);
1117 : /*
1118 : * Don't free current_dir_fname here. It's either been moved
1119 : * to the memcache or is being returned in result.
1120 : */
1121 2400439 : return result;
1122 : }
1123 :
1124 : /*
1125 : * Ensure LSTAT is called for POSIX paths.
1126 : */
1127 36516 : int vfs_stat(struct connection_struct *conn,
1128 : struct smb_filename *smb_fname)
1129 : {
1130 36516 : if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1131 88 : return SMB_VFS_LSTAT(conn, smb_fname);
1132 : }
1133 36428 : return SMB_VFS_STAT(conn, smb_fname);
1134 : }
1135 :
1136 : /**
1137 : * XXX: This is temporary and there should be no callers of this once
1138 : * smb_filename is plumbed through all path based operations.
1139 : *
1140 : * Called when we know stream name parsing has already been done.
1141 : */
1142 0 : int vfs_stat_smb_basename(struct connection_struct *conn,
1143 : const struct smb_filename *smb_fname_in,
1144 : SMB_STRUCT_STAT *psbuf)
1145 : {
1146 0 : struct smb_filename smb_fname = {
1147 0 : .base_name = discard_const_p(char, smb_fname_in->base_name),
1148 0 : .flags = smb_fname_in->flags,
1149 0 : .twrp = smb_fname_in->twrp,
1150 : };
1151 0 : int ret;
1152 :
1153 0 : ret = vfs_stat(conn, &smb_fname);
1154 0 : if (ret != -1) {
1155 0 : *psbuf = smb_fname.st;
1156 : }
1157 0 : return ret;
1158 : }
1159 :
1160 : /**
1161 : * Ensure LSTAT is called for POSIX paths.
1162 : */
1163 :
1164 4396319 : NTSTATUS vfs_stat_fsp(files_struct *fsp)
1165 : {
1166 14255 : int ret;
1167 4396319 : struct stat_ex saved_stat = fsp->fsp_name->st;
1168 :
1169 4396319 : if (fsp->fake_file_handle != NULL) {
1170 0 : return NT_STATUS_OK;
1171 : }
1172 :
1173 4396319 : if (fsp_get_pathref_fd(fsp) == -1) {
1174 67 : if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1175 67 : ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1176 : } else {
1177 0 : ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1178 : }
1179 : } else {
1180 4396252 : ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
1181 : }
1182 4396319 : if (ret == -1) {
1183 2 : return map_nt_error_from_unix(errno);
1184 : }
1185 4396317 : update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat);
1186 4396317 : fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
1187 4396317 : return NT_STATUS_OK;
1188 : }
1189 :
1190 368847 : void init_smb_file_time(struct smb_file_time *ft)
1191 : {
1192 369663 : *ft = (struct smb_file_time) {
1193 368847 : .atime = make_omit_timespec(),
1194 368847 : .ctime = make_omit_timespec(),
1195 368847 : .mtime = make_omit_timespec(),
1196 368847 : .create_time = make_omit_timespec()
1197 : };
1198 368847 : }
1199 :
1200 : /**
1201 : * Initialize num_streams and streams, then call VFS op streaminfo
1202 : */
1203 :
1204 317096 : NTSTATUS vfs_fstreaminfo(struct files_struct *fsp,
1205 : TALLOC_CTX *mem_ctx,
1206 : unsigned int *num_streams,
1207 : struct stream_struct **streams)
1208 : {
1209 317096 : *num_streams = 0;
1210 317096 : *streams = NULL;
1211 :
1212 317096 : if (fsp == NULL) {
1213 : /*
1214 : * Callers may pass fsp == NULL when passing smb_fname->fsp of a
1215 : * symlink. This is ok, handle it here, by just return no
1216 : * streams on a symlink.
1217 : */
1218 0 : return NT_STATUS_OK;
1219 : }
1220 :
1221 317096 : if (fsp_get_pathref_fd(fsp) == -1) {
1222 : /*
1223 : * No streams on non-real files/directories.
1224 : */
1225 128 : return NT_STATUS_OK;
1226 : }
1227 :
1228 316968 : return SMB_VFS_FSTREAMINFO(fsp,
1229 : mem_ctx,
1230 : num_streams,
1231 : streams);
1232 : }
1233 :
1234 5416 : int vfs_fake_fd(void)
1235 : {
1236 0 : int pipe_fds[2];
1237 0 : int ret;
1238 :
1239 : /*
1240 : * Return a valid fd, but ensure any attempt to use
1241 : * it returns an error (EPIPE).
1242 : */
1243 5416 : ret = pipe(pipe_fds);
1244 5416 : if (ret != 0) {
1245 0 : return -1;
1246 : }
1247 :
1248 5416 : close(pipe_fds[1]);
1249 5416 : return pipe_fds[0];
1250 : }
1251 :
1252 : /*
1253 : * This is just a helper to make
1254 : * users of vfs_fake_fd() more symmetric
1255 : */
1256 5042 : int vfs_fake_fd_close(int fd)
1257 : {
1258 5042 : return close(fd);
1259 : }
1260 :
1261 : /*
1262 : generate a file_id from a stat structure
1263 : */
1264 9017162 : struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1265 : {
1266 9017162 : return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1267 : }
1268 :
1269 9661 : NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
1270 : struct connection_struct *conn,
1271 : struct files_struct **_fsp)
1272 : {
1273 9661 : struct files_struct *fsp = NULL;
1274 :
1275 9661 : fsp = talloc_zero(mem_ctx, struct files_struct);
1276 9661 : if (fsp == NULL) {
1277 0 : return NT_STATUS_NO_MEMORY;
1278 : }
1279 :
1280 9661 : fsp->fsp_name = synthetic_smb_fname(fsp, ".", NULL, NULL, 0, 0);
1281 9661 : if (fsp->fsp_name == NULL) {
1282 0 : TALLOC_FREE(fsp);
1283 0 : return NT_STATUS_NO_MEMORY;
1284 : }
1285 :
1286 9661 : fsp->fh = fd_handle_create(fsp);
1287 9661 : if (fsp->fh == NULL) {
1288 0 : TALLOC_FREE(fsp);
1289 0 : return NT_STATUS_NO_MEMORY;
1290 : }
1291 :
1292 9661 : fsp_set_fd(fsp, AT_FDCWD);
1293 9661 : fsp->fnum = FNUM_FIELD_INVALID;
1294 9661 : fsp->conn = conn;
1295 :
1296 9661 : *_fsp = fsp;
1297 9661 : return NT_STATUS_OK;
1298 : }
1299 :
1300 1440227 : NTSTATUS vfs_fget_dos_attributes(struct files_struct *fsp,
1301 : uint32_t *dosmode)
1302 : {
1303 2249 : NTSTATUS status;
1304 :
1305 : /*
1306 : * First make sure to pass the base_fsp to the VFS
1307 : */
1308 1440227 : status = SMB_VFS_FGET_DOS_ATTRIBUTES(
1309 : fsp->conn, metadata_fsp(fsp), dosmode);
1310 1440227 : if (!NT_STATUS_IS_OK(status)) {
1311 119343 : return status;
1312 : }
1313 :
1314 : /*
1315 : * If this isn't a stream fsp we're done, ...
1316 : */
1317 1320884 : if (!fsp_is_alternate_stream(fsp)) {
1318 1313427 : return NT_STATUS_OK;
1319 : }
1320 :
1321 : /*
1322 : * ...otherwise the VFS might have updated the btime, propagate the
1323 : * btime from the base_fsp to the stream fsp.
1324 : */
1325 :
1326 7457 : if (fsp->base_fsp->fsp_name->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_BTIME) {
1327 : /*
1328 : * Not a value from backend storage, ignore it
1329 : */
1330 0 : return NT_STATUS_OK;
1331 : }
1332 :
1333 7457 : update_stat_ex_create_time(&fsp->fsp_name->st,
1334 7455 : fsp->base_fsp->fsp_name->st.st_ex_btime);
1335 :
1336 7457 : return NT_STATUS_OK;
1337 : }
1338 :
1339 : static struct smb_vfs_deny_state *smb_vfs_deny_global;
1340 :
1341 14522 : void smb_vfs_assert_allowed(void)
1342 : {
1343 14522 : if (unlikely(smb_vfs_deny_global != NULL)) {
1344 0 : DBG_ERR("Called with VFS denied by %s\n",
1345 : smb_vfs_deny_global->location);
1346 0 : smb_panic("Called with VFS denied!");
1347 : }
1348 14522 : }
1349 :
1350 1104759 : void _smb_vfs_deny_push(struct smb_vfs_deny_state *state, const char *location)
1351 : {
1352 1104759 : SMB_ASSERT(smb_vfs_deny_global != state);
1353 :
1354 1104759 : *state = (struct smb_vfs_deny_state) {
1355 : .parent = smb_vfs_deny_global,
1356 : .location = location,
1357 : };
1358 :
1359 1104759 : smb_vfs_deny_global = state;
1360 1104759 : }
1361 :
1362 1104759 : void _smb_vfs_deny_pop(struct smb_vfs_deny_state *state, const char *location)
1363 : {
1364 1104759 : SMB_ASSERT(smb_vfs_deny_global == state);
1365 :
1366 1104759 : smb_vfs_deny_global = state->parent;
1367 :
1368 1104759 : *state = (struct smb_vfs_deny_state) { .parent = NULL, };
1369 1104759 : }
1370 :
1371 : #define VFS_FIND(__fn__) do { \
1372 : if (unlikely(smb_vfs_deny_global != NULL)) { \
1373 : DBG_ERR("Called with VFS denied by %s\n", \
1374 : smb_vfs_deny_global->location); \
1375 : smb_panic("Called with VFS denied!"); \
1376 : } \
1377 : while (handle->fns->__fn__##_fn==NULL) { \
1378 : handle = handle->next; \
1379 : } \
1380 : } while(0)
1381 :
1382 306165 : int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1383 : const char *service, const char *user)
1384 : {
1385 357818 : VFS_FIND(connect);
1386 306165 : return handle->fns->connect_fn(handle, service, user);
1387 : }
1388 :
1389 145636 : void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1390 : {
1391 357494 : VFS_FIND(disconnect);
1392 145636 : handle->fns->disconnect_fn(handle);
1393 145636 : }
1394 :
1395 3692 : uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1396 : const struct smb_filename *smb_fname,
1397 : uint64_t *bsize,
1398 : uint64_t *dfree,
1399 : uint64_t *dsize)
1400 : {
1401 9967 : VFS_FIND(disk_free);
1402 3692 : return handle->fns->disk_free_fn(handle, smb_fname,
1403 : bsize, dfree, dsize);
1404 : }
1405 :
1406 7658 : int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1407 : const struct smb_filename *smb_fname,
1408 : enum SMB_QUOTA_TYPE qtype,
1409 : unid_t id,
1410 : SMB_DISK_QUOTA *qt)
1411 : {
1412 20658 : VFS_FIND(get_quota);
1413 7658 : return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1414 : }
1415 :
1416 12 : int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1417 : enum SMB_QUOTA_TYPE qtype, unid_t id,
1418 : SMB_DISK_QUOTA *qt)
1419 : {
1420 28 : VFS_FIND(set_quota);
1421 12 : return handle->fns->set_quota_fn(handle, qtype, id, qt);
1422 : }
1423 :
1424 3256 : int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1425 : struct files_struct *fsp,
1426 : struct shadow_copy_data *shadow_copy_data,
1427 : bool labels)
1428 : {
1429 4316 : VFS_FIND(get_shadow_copy_data);
1430 3256 : return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1431 : shadow_copy_data,
1432 : labels);
1433 : }
1434 66852 : int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1435 : const struct smb_filename *smb_fname,
1436 : struct vfs_statvfs_struct *statbuf)
1437 : {
1438 183833 : VFS_FIND(statvfs);
1439 66852 : return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1440 : }
1441 :
1442 92698 : uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1443 : enum timestamp_set_resolution *p_ts_res)
1444 : {
1445 183833 : VFS_FIND(fs_capabilities);
1446 92698 : return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1447 : }
1448 :
1449 43514 : NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1450 : struct dfs_GetDFSReferral *r)
1451 : {
1452 102006 : VFS_FIND(get_dfs_referrals);
1453 43514 : return handle->fns->get_dfs_referrals_fn(handle, r);
1454 : }
1455 :
1456 0 : NTSTATUS smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct *handle,
1457 : struct files_struct *dirfsp,
1458 : const struct smb_filename *smb_fname,
1459 : const struct referral *reflist,
1460 : size_t referral_count)
1461 : {
1462 0 : VFS_FIND(create_dfs_pathat);
1463 0 : return handle->fns->create_dfs_pathat_fn(handle,
1464 : dirfsp,
1465 : smb_fname,
1466 : reflist,
1467 : referral_count);
1468 : }
1469 :
1470 13302 : NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
1471 : TALLOC_CTX *mem_ctx,
1472 : struct files_struct *dirfsp,
1473 : struct smb_filename *smb_fname,
1474 : struct referral **ppreflist,
1475 : size_t *preferral_count)
1476 : {
1477 31040 : VFS_FIND(read_dfs_pathat);
1478 13302 : return handle->fns->read_dfs_pathat_fn(handle,
1479 : mem_ctx,
1480 : dirfsp,
1481 : smb_fname,
1482 : ppreflist,
1483 : preferral_count);
1484 : }
1485 :
1486 620442 : DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1487 : struct files_struct *fsp,
1488 : const char *mask,
1489 : uint32_t attributes)
1490 : {
1491 1883050 : VFS_FIND(fdopendir);
1492 620442 : return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1493 : }
1494 :
1495 322512640 : struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1496 : struct files_struct *dirfsp,
1497 : DIR *dirp)
1498 : {
1499 870571143 : VFS_FIND(readdir);
1500 322512640 : return handle->fns->readdir_fn(handle, dirfsp, dirp);
1501 : }
1502 :
1503 5724 : void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1504 : DIR *dirp)
1505 : {
1506 17242 : VFS_FIND(rewind_dir);
1507 5724 : handle->fns->rewind_dir_fn(handle, dirp);
1508 5724 : }
1509 :
1510 37278 : int smb_vfs_call_mkdirat(struct vfs_handle_struct *handle,
1511 : struct files_struct *dirfsp,
1512 : const struct smb_filename *smb_fname,
1513 : mode_t mode)
1514 : {
1515 75181 : VFS_FIND(mkdirat);
1516 37278 : return handle->fns->mkdirat_fn(handle,
1517 : dirfsp,
1518 : smb_fname,
1519 : mode);
1520 : }
1521 :
1522 620442 : int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1523 : DIR *dir)
1524 : {
1525 1883050 : VFS_FIND(closedir);
1526 620442 : return handle->fns->closedir_fn(handle, dir);
1527 : }
1528 :
1529 25085757 : int smb_vfs_call_openat(struct vfs_handle_struct *handle,
1530 : const struct files_struct *dirfsp,
1531 : const struct smb_filename *smb_fname,
1532 : struct files_struct *fsp,
1533 : const struct vfs_open_how *how)
1534 : {
1535 39074311 : VFS_FIND(openat);
1536 25085757 : return handle->fns->openat_fn(handle,
1537 : dirfsp,
1538 : smb_fname,
1539 : fsp,
1540 : how);
1541 : }
1542 :
1543 1118568 : NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1544 : struct smb_request *req,
1545 : struct files_struct *dirfsp,
1546 : struct smb_filename *smb_fname,
1547 : uint32_t access_mask,
1548 : uint32_t share_access,
1549 : uint32_t create_disposition,
1550 : uint32_t create_options,
1551 : uint32_t file_attributes,
1552 : uint32_t oplock_request,
1553 : const struct smb2_lease *lease,
1554 : uint64_t allocation_size,
1555 : uint32_t private_flags,
1556 : struct security_descriptor *sd,
1557 : struct ea_list *ea_list,
1558 : files_struct **result,
1559 : int *pinfo,
1560 : const struct smb2_create_blobs *in_context_blobs,
1561 : struct smb2_create_blobs *out_context_blobs)
1562 : {
1563 3369190 : VFS_FIND(create_file);
1564 1118568 : return handle->fns->create_file_fn(
1565 : handle, req, dirfsp, smb_fname,
1566 : access_mask, share_access, create_disposition, create_options,
1567 : file_attributes, oplock_request, lease, allocation_size,
1568 : private_flags, sd, ea_list,
1569 : result, pinfo, in_context_blobs, out_context_blobs);
1570 : }
1571 :
1572 8612934 : int smb_vfs_call_close(struct vfs_handle_struct *handle,
1573 : struct files_struct *fsp)
1574 : {
1575 25859771 : VFS_FIND(close);
1576 8612934 : return handle->fns->close_fn(handle, fsp);
1577 : }
1578 :
1579 11826 : ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1580 : struct files_struct *fsp, void *data, size_t n,
1581 : off_t offset)
1582 : {
1583 24958 : VFS_FIND(pread);
1584 11826 : return handle->fns->pread_fn(handle, fsp, data, n, offset);
1585 : }
1586 :
1587 : struct smb_vfs_call_pread_state {
1588 : ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1589 : ssize_t retval;
1590 : struct vfs_aio_state vfs_aio_state;
1591 : };
1592 :
1593 : static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1594 :
1595 32388 : struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1596 : TALLOC_CTX *mem_ctx,
1597 : struct tevent_context *ev,
1598 : struct files_struct *fsp,
1599 : void *data,
1600 : size_t n, off_t offset)
1601 : {
1602 42 : struct tevent_req *req, *subreq;
1603 42 : struct smb_vfs_call_pread_state *state;
1604 :
1605 32388 : req = tevent_req_create(mem_ctx, &state,
1606 : struct smb_vfs_call_pread_state);
1607 32388 : if (req == NULL) {
1608 0 : return NULL;
1609 : }
1610 83143 : VFS_FIND(pread_send);
1611 32388 : state->recv_fn = handle->fns->pread_recv_fn;
1612 :
1613 32388 : subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1614 : offset);
1615 32388 : if (tevent_req_nomem(subreq, req)) {
1616 0 : return tevent_req_post(req, ev);
1617 : }
1618 32388 : tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1619 32388 : return req;
1620 : }
1621 :
1622 32388 : static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1623 : {
1624 32388 : struct tevent_req *req = tevent_req_callback_data(
1625 : subreq, struct tevent_req);
1626 32388 : struct smb_vfs_call_pread_state *state = tevent_req_data(
1627 : req, struct smb_vfs_call_pread_state);
1628 :
1629 32388 : state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1630 32388 : TALLOC_FREE(subreq);
1631 32388 : if (state->retval == -1) {
1632 0 : tevent_req_error(req, state->vfs_aio_state.error);
1633 0 : return;
1634 : }
1635 32388 : tevent_req_done(req);
1636 : }
1637 :
1638 32388 : ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1639 : struct vfs_aio_state *vfs_aio_state)
1640 : {
1641 32388 : struct smb_vfs_call_pread_state *state = tevent_req_data(
1642 : req, struct smb_vfs_call_pread_state);
1643 42 : ssize_t retval;
1644 :
1645 32388 : if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1646 0 : tevent_req_received(req);
1647 0 : return -1;
1648 : }
1649 32388 : *vfs_aio_state = state->vfs_aio_state;
1650 32388 : retval = state->retval;
1651 32388 : tevent_req_received(req);
1652 32388 : return retval;
1653 : }
1654 :
1655 6404 : ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1656 : struct files_struct *fsp, const void *data,
1657 : size_t n, off_t offset)
1658 : {
1659 9412 : VFS_FIND(pwrite);
1660 6404 : return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1661 : }
1662 :
1663 : struct smb_vfs_call_pwrite_state {
1664 : ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1665 : ssize_t retval;
1666 : struct vfs_aio_state vfs_aio_state;
1667 : };
1668 :
1669 : static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1670 :
1671 418370 : struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1672 : TALLOC_CTX *mem_ctx,
1673 : struct tevent_context *ev,
1674 : struct files_struct *fsp,
1675 : const void *data,
1676 : size_t n, off_t offset)
1677 : {
1678 52 : struct tevent_req *req, *subreq;
1679 52 : struct smb_vfs_call_pwrite_state *state;
1680 :
1681 418370 : req = tevent_req_create(mem_ctx, &state,
1682 : struct smb_vfs_call_pwrite_state);
1683 418370 : if (req == NULL) {
1684 0 : return NULL;
1685 : }
1686 999732 : VFS_FIND(pwrite_send);
1687 418370 : state->recv_fn = handle->fns->pwrite_recv_fn;
1688 :
1689 418370 : subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1690 : offset);
1691 418370 : if (tevent_req_nomem(subreq, req)) {
1692 0 : return tevent_req_post(req, ev);
1693 : }
1694 418370 : tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1695 418370 : return req;
1696 : }
1697 :
1698 418366 : static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1699 : {
1700 418366 : struct tevent_req *req = tevent_req_callback_data(
1701 : subreq, struct tevent_req);
1702 418366 : struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1703 : req, struct smb_vfs_call_pwrite_state);
1704 :
1705 418366 : state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1706 418366 : TALLOC_FREE(subreq);
1707 418366 : if (state->retval == -1) {
1708 0 : tevent_req_error(req, state->vfs_aio_state.error);
1709 0 : return;
1710 : }
1711 418366 : tevent_req_done(req);
1712 : }
1713 :
1714 418366 : ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1715 : struct vfs_aio_state *vfs_aio_state)
1716 : {
1717 418366 : struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1718 : req, struct smb_vfs_call_pwrite_state);
1719 52 : ssize_t retval;
1720 :
1721 418366 : if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1722 0 : tevent_req_received(req);
1723 0 : return -1;
1724 : }
1725 418366 : *vfs_aio_state = state->vfs_aio_state;
1726 418366 : retval = state->retval;
1727 418366 : tevent_req_received(req);
1728 418366 : return retval;
1729 : }
1730 :
1731 1109 : off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1732 : struct files_struct *fsp, off_t offset,
1733 : int whence)
1734 : {
1735 3112 : VFS_FIND(lseek);
1736 1109 : return handle->fns->lseek_fn(handle, fsp, offset, whence);
1737 : }
1738 :
1739 0 : ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1740 : files_struct *fromfsp, const DATA_BLOB *header,
1741 : off_t offset, size_t count)
1742 : {
1743 0 : VFS_FIND(sendfile);
1744 0 : return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1745 : count);
1746 : }
1747 :
1748 0 : ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1749 : files_struct *tofsp, off_t offset,
1750 : size_t count)
1751 : {
1752 0 : VFS_FIND(recvfile);
1753 0 : return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1754 : }
1755 :
1756 3262 : int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
1757 : files_struct *srcfsp,
1758 : const struct smb_filename *smb_fname_src,
1759 : files_struct *dstfsp,
1760 : const struct smb_filename *smb_fname_dst)
1761 : {
1762 6412 : VFS_FIND(renameat);
1763 3262 : return handle->fns->renameat_fn(handle,
1764 : srcfsp,
1765 : smb_fname_src,
1766 : dstfsp,
1767 : smb_fname_dst);
1768 : }
1769 :
1770 : struct smb_vfs_call_fsync_state {
1771 : int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1772 : int retval;
1773 : struct vfs_aio_state vfs_aio_state;
1774 : };
1775 :
1776 : static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1777 :
1778 404 : struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1779 : TALLOC_CTX *mem_ctx,
1780 : struct tevent_context *ev,
1781 : struct files_struct *fsp)
1782 : {
1783 2 : struct tevent_req *req, *subreq;
1784 2 : struct smb_vfs_call_fsync_state *state;
1785 :
1786 404 : req = tevent_req_create(mem_ctx, &state,
1787 : struct smb_vfs_call_fsync_state);
1788 404 : if (req == NULL) {
1789 0 : return NULL;
1790 : }
1791 968 : VFS_FIND(fsync_send);
1792 404 : state->recv_fn = handle->fns->fsync_recv_fn;
1793 :
1794 404 : subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1795 404 : if (tevent_req_nomem(subreq, req)) {
1796 0 : return tevent_req_post(req, ev);
1797 : }
1798 404 : tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1799 404 : return req;
1800 : }
1801 :
1802 404 : static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1803 : {
1804 404 : struct tevent_req *req = tevent_req_callback_data(
1805 : subreq, struct tevent_req);
1806 404 : struct smb_vfs_call_fsync_state *state = tevent_req_data(
1807 : req, struct smb_vfs_call_fsync_state);
1808 :
1809 404 : state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1810 404 : TALLOC_FREE(subreq);
1811 404 : if (state->retval == -1) {
1812 0 : tevent_req_error(req, state->vfs_aio_state.error);
1813 0 : return;
1814 : }
1815 404 : tevent_req_done(req);
1816 : }
1817 :
1818 404 : int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1819 : {
1820 404 : struct smb_vfs_call_fsync_state *state = tevent_req_data(
1821 : req, struct smb_vfs_call_fsync_state);
1822 2 : ssize_t retval;
1823 :
1824 404 : if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1825 0 : tevent_req_received(req);
1826 0 : return -1;
1827 : }
1828 404 : *vfs_aio_state = state->vfs_aio_state;
1829 404 : retval = state->retval;
1830 404 : tevent_req_received(req);
1831 404 : return retval;
1832 : }
1833 :
1834 : /*
1835 : * Synchronous version of fsync, built from backend
1836 : * async VFS primitives. Uses a temporary sub-event
1837 : * context (NOT NESTED).
1838 : */
1839 :
1840 7 : int smb_vfs_fsync_sync(files_struct *fsp)
1841 : {
1842 7 : TALLOC_CTX *frame = talloc_stackframe();
1843 7 : struct tevent_req *req = NULL;
1844 7 : struct vfs_aio_state aio_state = { 0 };
1845 7 : int ret = -1;
1846 1 : bool ok;
1847 7 : struct tevent_context *ev = samba_tevent_context_init(frame);
1848 :
1849 7 : if (ev == NULL) {
1850 0 : goto out;
1851 : }
1852 :
1853 7 : req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
1854 7 : if (req == NULL) {
1855 0 : goto out;
1856 : }
1857 :
1858 7 : ok = tevent_req_poll(req, ev);
1859 7 : if (!ok) {
1860 0 : goto out;
1861 : }
1862 :
1863 7 : ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
1864 :
1865 7 : out:
1866 :
1867 7 : TALLOC_FREE(frame);
1868 7 : if (aio_state.error != 0) {
1869 0 : errno = aio_state.error;
1870 : }
1871 7 : return ret;
1872 : }
1873 :
1874 21463300 : int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1875 : struct smb_filename *smb_fname)
1876 : {
1877 32849095 : VFS_FIND(stat);
1878 21463300 : return handle->fns->stat_fn(handle, smb_fname);
1879 : }
1880 :
1881 73528214 : int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1882 : struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1883 : {
1884 126279922 : VFS_FIND(fstat);
1885 73528214 : return handle->fns->fstat_fn(handle, fsp, sbuf);
1886 : }
1887 :
1888 105639 : int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1889 : struct smb_filename *smb_filename)
1890 : {
1891 142414 : VFS_FIND(lstat);
1892 105639 : return handle->fns->lstat_fn(handle, smb_filename);
1893 : }
1894 :
1895 118259 : int smb_vfs_call_fstatat(
1896 : struct vfs_handle_struct *handle,
1897 : const struct files_struct *dirfsp,
1898 : const struct smb_filename *smb_fname,
1899 : SMB_STRUCT_STAT *sbuf,
1900 : int flags)
1901 : {
1902 254130 : VFS_FIND(fstatat);
1903 118259 : return handle->fns->fstatat_fn(handle, dirfsp, smb_fname, sbuf, flags);
1904 : }
1905 :
1906 3383077 : uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1907 : struct files_struct *fsp,
1908 : const SMB_STRUCT_STAT *sbuf)
1909 : {
1910 10602725 : VFS_FIND(get_alloc_size);
1911 3383077 : return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1912 : }
1913 :
1914 802372 : int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle,
1915 : struct files_struct *dirfsp,
1916 : const struct smb_filename *smb_fname,
1917 : int flags)
1918 : {
1919 1034247 : VFS_FIND(unlinkat);
1920 802372 : return handle->fns->unlinkat_fn(handle,
1921 : dirfsp,
1922 : smb_fname,
1923 : flags);
1924 : }
1925 :
1926 20995 : int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1927 : struct files_struct *fsp, mode_t mode)
1928 : {
1929 51988 : VFS_FIND(fchmod);
1930 20995 : return handle->fns->fchmod_fn(handle, fsp, mode);
1931 : }
1932 :
1933 213842 : int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1934 : struct files_struct *fsp, uid_t uid, gid_t gid)
1935 : {
1936 553893 : VFS_FIND(fchown);
1937 213842 : return handle->fns->fchown_fn(handle, fsp, uid, gid);
1938 : }
1939 :
1940 0 : int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
1941 : const struct smb_filename *smb_fname,
1942 : uid_t uid,
1943 : gid_t gid)
1944 : {
1945 0 : VFS_FIND(lchown);
1946 0 : return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
1947 : }
1948 :
1949 3869331 : int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
1950 : const struct smb_filename *smb_fname)
1951 : {
1952 11491659 : VFS_FIND(chdir);
1953 3869331 : return handle->fns->chdir_fn(handle, smb_fname);
1954 : }
1955 :
1956 200579 : struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
1957 : TALLOC_CTX *ctx)
1958 : {
1959 531375 : VFS_FIND(getwd);
1960 200579 : return handle->fns->getwd_fn(handle, ctx);
1961 : }
1962 :
1963 27146 : int smb_vfs_call_fntimes(struct vfs_handle_struct *handle,
1964 : struct files_struct *fsp,
1965 : struct smb_file_time *ft)
1966 : {
1967 71158 : VFS_FIND(fntimes);
1968 27146 : return handle->fns->fntimes_fn(handle, fsp, ft);
1969 : }
1970 :
1971 2453 : int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1972 : struct files_struct *fsp, off_t offset)
1973 : {
1974 7307 : VFS_FIND(ftruncate);
1975 2453 : return handle->fns->ftruncate_fn(handle, fsp, offset);
1976 : }
1977 :
1978 466 : int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1979 : struct files_struct *fsp,
1980 : uint32_t mode,
1981 : off_t offset,
1982 : off_t len)
1983 : {
1984 1302 : VFS_FIND(fallocate);
1985 466 : return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1986 : }
1987 :
1988 0 : int smb_vfs_call_filesystem_sharemode(struct vfs_handle_struct *handle,
1989 : struct files_struct *fsp,
1990 : uint32_t share_mode,
1991 : uint32_t access_mask)
1992 : {
1993 0 : VFS_FIND(filesystem_sharemode);
1994 0 : return handle->fns->filesystem_sharemode_fn(handle,
1995 : fsp,
1996 : share_mode,
1997 : access_mask);
1998 : }
1999 :
2000 771934 : int smb_vfs_call_fcntl(struct vfs_handle_struct *handle,
2001 : struct files_struct *fsp, int cmd, ...)
2002 : {
2003 898 : int result;
2004 898 : va_list cmd_arg;
2005 :
2006 2312400 : VFS_FIND(fcntl);
2007 :
2008 771934 : va_start(cmd_arg, cmd);
2009 771934 : result = handle->fns->fcntl_fn(handle, fsp, cmd, cmd_arg);
2010 771934 : va_end(cmd_arg);
2011 :
2012 771934 : return result;
2013 : }
2014 :
2015 26 : int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2016 : struct files_struct *fsp, int leasetype)
2017 : {
2018 38 : VFS_FIND(linux_setlease);
2019 26 : return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2020 : }
2021 :
2022 160 : int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle,
2023 : const struct smb_filename *link_target,
2024 : struct files_struct *dirfsp,
2025 : const struct smb_filename *new_smb_fname)
2026 : {
2027 448 : VFS_FIND(symlinkat);
2028 160 : return handle->fns->symlinkat_fn(handle,
2029 : link_target,
2030 : dirfsp,
2031 : new_smb_fname);
2032 : }
2033 :
2034 224303 : int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2035 : const struct files_struct *dirfsp,
2036 : const struct smb_filename *smb_fname,
2037 : char *buf,
2038 : size_t bufsiz)
2039 : {
2040 515771 : VFS_FIND(readlinkat);
2041 224303 : return handle->fns->readlinkat_fn(handle,
2042 : dirfsp,
2043 : smb_fname,
2044 : buf,
2045 : bufsiz);
2046 : }
2047 :
2048 107 : int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2049 : struct files_struct *srcfsp,
2050 : const struct smb_filename *old_smb_fname,
2051 : struct files_struct *dstfsp,
2052 : const struct smb_filename *new_smb_fname,
2053 : int flags)
2054 : {
2055 266 : VFS_FIND(linkat);
2056 107 : return handle->fns->linkat_fn(handle,
2057 : srcfsp,
2058 : old_smb_fname,
2059 : dstfsp,
2060 : new_smb_fname,
2061 : flags);
2062 : }
2063 :
2064 2 : int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2065 : struct files_struct *dirfsp,
2066 : const struct smb_filename *smb_fname,
2067 : mode_t mode,
2068 : SMB_DEV_T dev)
2069 : {
2070 6 : VFS_FIND(mknodat);
2071 2 : return handle->fns->mknodat_fn(handle,
2072 : dirfsp,
2073 : smb_fname,
2074 : mode,
2075 : dev);
2076 : }
2077 :
2078 7648372 : struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2079 : TALLOC_CTX *ctx,
2080 : const struct smb_filename *smb_fname)
2081 : {
2082 22881154 : VFS_FIND(realpath);
2083 7648372 : return handle->fns->realpath_fn(handle, ctx, smb_fname);
2084 : }
2085 :
2086 0 : int smb_vfs_call_fchflags(struct vfs_handle_struct *handle,
2087 : struct files_struct *fsp,
2088 : unsigned int flags)
2089 : {
2090 0 : VFS_FIND(fchflags);
2091 0 : return handle->fns->fchflags_fn(handle, fsp, flags);
2092 : }
2093 :
2094 69026613 : struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2095 : const SMB_STRUCT_STAT *sbuf)
2096 : {
2097 135103052 : VFS_FIND(file_id_create);
2098 69026613 : return handle->fns->file_id_create_fn(handle, sbuf);
2099 : }
2100 :
2101 1781421 : uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2102 : const SMB_STRUCT_STAT *sbuf)
2103 : {
2104 5747541 : VFS_FIND(fs_file_id);
2105 1781421 : return handle->fns->fs_file_id_fn(handle, sbuf);
2106 : }
2107 :
2108 995312 : NTSTATUS smb_vfs_call_fstreaminfo(struct vfs_handle_struct *handle,
2109 : struct files_struct *fsp,
2110 : TALLOC_CTX *mem_ctx,
2111 : unsigned int *num_streams,
2112 : struct stream_struct **streams)
2113 : {
2114 2061954 : VFS_FIND(fstreaminfo);
2115 995312 : return handle->fns->fstreaminfo_fn(handle, fsp, mem_ctx,
2116 : num_streams, streams);
2117 : }
2118 :
2119 548384 : NTSTATUS smb_vfs_call_get_real_filename_at(struct vfs_handle_struct *handle,
2120 : struct files_struct *dirfsp,
2121 : const char *name,
2122 : TALLOC_CTX *mem_ctx,
2123 : char **found_name)
2124 : {
2125 1680507 : VFS_FIND(get_real_filename_at);
2126 548384 : return handle->fns->get_real_filename_at_fn(
2127 : handle, dirfsp, name, mem_ctx, found_name);
2128 : }
2129 :
2130 8352181 : const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2131 : const struct files_struct *dirfsp,
2132 : const struct smb_filename *smb_fname)
2133 : {
2134 25257484 : VFS_FIND(connectpath);
2135 8352181 : return handle->fns->connectpath_fn(handle, dirfsp, smb_fname);
2136 : }
2137 :
2138 461085 : bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2139 : struct files_struct *fsp,
2140 : struct lock_struct *plock)
2141 : {
2142 1153185 : VFS_FIND(strict_lock_check);
2143 461085 : return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2144 : }
2145 :
2146 320271241 : NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2147 : const char *name,
2148 : enum vfs_translate_direction direction,
2149 : TALLOC_CTX *mem_ctx,
2150 : char **mapped_name)
2151 : {
2152 869043884 : VFS_FIND(translate_name);
2153 320271241 : return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2154 : mapped_name);
2155 : }
2156 :
2157 8865211 : NTSTATUS smb_vfs_call_parent_pathname(struct vfs_handle_struct *handle,
2158 : TALLOC_CTX *mem_ctx,
2159 : const struct smb_filename *smb_fname_in,
2160 : struct smb_filename **parent_dir_out,
2161 : struct smb_filename **atname_out)
2162 : {
2163 26792057 : VFS_FIND(parent_pathname);
2164 8865211 : return handle->fns->parent_pathname_fn(handle,
2165 : mem_ctx,
2166 : smb_fname_in,
2167 : parent_dir_out,
2168 : atname_out);
2169 : }
2170 :
2171 4116 : NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2172 : struct files_struct *fsp,
2173 : TALLOC_CTX *ctx,
2174 : uint32_t function,
2175 : uint16_t req_flags,
2176 : const uint8_t *in_data,
2177 : uint32_t in_len,
2178 : uint8_t **out_data,
2179 : uint32_t max_out_len,
2180 : uint32_t *out_len)
2181 : {
2182 9418 : VFS_FIND(fsctl);
2183 4116 : return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2184 : in_data, in_len, out_data, max_out_len,
2185 : out_len);
2186 : }
2187 :
2188 2853855 : NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2189 : struct files_struct *fsp,
2190 : uint32_t *dosmode)
2191 : {
2192 9002064 : VFS_FIND(fget_dos_attributes);
2193 2853855 : return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2194 : }
2195 :
2196 350122 : NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2197 : struct files_struct *fsp,
2198 : uint32_t dosmode)
2199 : {
2200 1061200 : VFS_FIND(fset_dos_attributes);
2201 350122 : return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2202 : }
2203 :
2204 680 : struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2205 : struct tevent_context *ev,
2206 : struct vfs_handle_struct *handle,
2207 : struct files_struct *fsp,
2208 : uint32_t fsctl,
2209 : uint32_t ttl,
2210 : off_t offset,
2211 : size_t to_copy)
2212 : {
2213 1890 : VFS_FIND(offload_read_send);
2214 680 : return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2215 : fsp, fsctl,
2216 : ttl, offset, to_copy);
2217 : }
2218 :
2219 680 : NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2220 : struct vfs_handle_struct *handle,
2221 : TALLOC_CTX *mem_ctx,
2222 : uint32_t *flags,
2223 : uint64_t *xferlen,
2224 : DATA_BLOB *token_blob)
2225 : {
2226 1890 : VFS_FIND(offload_read_recv);
2227 680 : return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, flags, xferlen, token_blob);
2228 : }
2229 :
2230 760 : struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2231 : TALLOC_CTX *mem_ctx,
2232 : struct tevent_context *ev,
2233 : uint32_t fsctl,
2234 : DATA_BLOB *token,
2235 : off_t transfer_offset,
2236 : struct files_struct *dest_fsp,
2237 : off_t dest_off,
2238 : off_t num)
2239 : {
2240 2114 : VFS_FIND(offload_write_send);
2241 760 : return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2242 : token, transfer_offset,
2243 : dest_fsp, dest_off, num);
2244 : }
2245 :
2246 760 : NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2247 : struct tevent_req *req,
2248 : off_t *copied)
2249 : {
2250 2114 : VFS_FIND(offload_write_recv);
2251 760 : return handle->fns->offload_write_recv_fn(handle, req, copied);
2252 : }
2253 :
2254 : struct smb_vfs_call_get_dos_attributes_state {
2255 : files_struct *dir_fsp;
2256 : NTSTATUS (*recv_fn)(struct tevent_req *req,
2257 : struct vfs_aio_state *aio_state,
2258 : uint32_t *dosmode);
2259 : struct vfs_aio_state aio_state;
2260 : uint32_t dos_attributes;
2261 : };
2262 :
2263 : static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2264 :
2265 20136 : struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2266 : TALLOC_CTX *mem_ctx,
2267 : struct tevent_context *ev,
2268 : struct vfs_handle_struct *handle,
2269 : files_struct *dir_fsp,
2270 : struct smb_filename *smb_fname)
2271 : {
2272 20136 : struct tevent_req *req = NULL;
2273 20136 : struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2274 20136 : struct tevent_req *subreq = NULL;
2275 :
2276 20136 : req = tevent_req_create(mem_ctx, &state,
2277 : struct smb_vfs_call_get_dos_attributes_state);
2278 20136 : if (req == NULL) {
2279 0 : return NULL;
2280 : }
2281 :
2282 50361 : VFS_FIND(get_dos_attributes_send);
2283 :
2284 20136 : *state = (struct smb_vfs_call_get_dos_attributes_state) {
2285 : .dir_fsp = dir_fsp,
2286 20136 : .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2287 : };
2288 :
2289 20136 : subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2290 : ev,
2291 : handle,
2292 : dir_fsp,
2293 : smb_fname);
2294 20136 : if (tevent_req_nomem(subreq, req)) {
2295 0 : return tevent_req_post(req, ev);
2296 : }
2297 20136 : tevent_req_defer_callback(req, ev);
2298 :
2299 20136 : tevent_req_set_callback(subreq,
2300 : smb_vfs_call_get_dos_attributes_done,
2301 : req);
2302 :
2303 20136 : return req;
2304 : }
2305 :
2306 20136 : static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2307 : {
2308 0 : struct tevent_req *req =
2309 20136 : tevent_req_callback_data(subreq,
2310 : struct tevent_req);
2311 0 : struct smb_vfs_call_get_dos_attributes_state *state =
2312 20136 : tevent_req_data(req,
2313 : struct smb_vfs_call_get_dos_attributes_state);
2314 0 : NTSTATUS status;
2315 0 : bool ok;
2316 :
2317 : /*
2318 : * Make sure we run as the user again
2319 : */
2320 20136 : ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2321 20136 : SMB_ASSERT(ok);
2322 :
2323 20136 : status = state->recv_fn(subreq,
2324 : &state->aio_state,
2325 : &state->dos_attributes);
2326 20136 : TALLOC_FREE(subreq);
2327 20136 : if (tevent_req_nterror(req, status)) {
2328 118 : return;
2329 : }
2330 :
2331 20018 : tevent_req_done(req);
2332 : }
2333 :
2334 20136 : NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2335 : struct tevent_req *req,
2336 : struct vfs_aio_state *aio_state,
2337 : uint32_t *dos_attributes)
2338 : {
2339 0 : struct smb_vfs_call_get_dos_attributes_state *state =
2340 20136 : tevent_req_data(req,
2341 : struct smb_vfs_call_get_dos_attributes_state);
2342 0 : NTSTATUS status;
2343 :
2344 20136 : if (tevent_req_is_nterror(req, &status)) {
2345 118 : tevent_req_received(req);
2346 118 : return status;
2347 : }
2348 :
2349 20018 : *aio_state = state->aio_state;
2350 20018 : *dos_attributes = state->dos_attributes;
2351 20018 : tevent_req_received(req);
2352 20018 : return NT_STATUS_OK;
2353 : }
2354 :
2355 0 : NTSTATUS smb_vfs_call_fget_compression(vfs_handle_struct *handle,
2356 : TALLOC_CTX *mem_ctx,
2357 : struct files_struct *fsp,
2358 : uint16_t *_compression_fmt)
2359 : {
2360 0 : VFS_FIND(fget_compression);
2361 0 : return handle->fns->fget_compression_fn(handle, mem_ctx, fsp,
2362 : _compression_fmt);
2363 : }
2364 :
2365 0 : NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2366 : TALLOC_CTX *mem_ctx,
2367 : struct files_struct *fsp,
2368 : uint16_t compression_fmt)
2369 : {
2370 0 : VFS_FIND(set_compression);
2371 0 : return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2372 : compression_fmt);
2373 : }
2374 :
2375 68 : NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2376 : TALLOC_CTX *mem_ctx,
2377 : const char *service_path,
2378 : char **base_volume)
2379 : {
2380 68 : VFS_FIND(snap_check_path);
2381 68 : return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2382 : base_volume);
2383 : }
2384 :
2385 16 : NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2386 : TALLOC_CTX *mem_ctx,
2387 : const char *base_volume,
2388 : time_t *tstamp,
2389 : bool rw,
2390 : char **base_path,
2391 : char **snap_path)
2392 : {
2393 16 : VFS_FIND(snap_create);
2394 16 : return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2395 : rw, base_path, snap_path);
2396 : }
2397 :
2398 10 : NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2399 : TALLOC_CTX *mem_ctx,
2400 : char *base_path,
2401 : char *snap_path)
2402 : {
2403 10 : VFS_FIND(snap_delete);
2404 10 : return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2405 : snap_path);
2406 : }
2407 :
2408 1509554 : NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2409 : struct files_struct *fsp,
2410 : uint32_t security_info,
2411 : TALLOC_CTX *mem_ctx,
2412 : struct security_descriptor **ppdesc)
2413 : {
2414 2913518 : VFS_FIND(fget_nt_acl);
2415 1509554 : return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2416 : mem_ctx, ppdesc);
2417 : }
2418 :
2419 497835 : NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2420 : struct files_struct *fsp,
2421 : uint32_t security_info_sent,
2422 : const struct security_descriptor *psd)
2423 : {
2424 1036253 : VFS_FIND(fset_nt_acl);
2425 497835 : return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2426 : psd);
2427 : }
2428 :
2429 0 : NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2430 : struct smb_filename *file,
2431 : struct security_acl *sacl,
2432 : uint32_t access_requested,
2433 : uint32_t access_denied)
2434 : {
2435 0 : VFS_FIND(audit_file);
2436 0 : return handle->fns->audit_file_fn(handle,
2437 : file,
2438 : sacl,
2439 : access_requested,
2440 : access_denied);
2441 : }
2442 :
2443 1931932 : SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2444 : struct files_struct *fsp,
2445 : SMB_ACL_TYPE_T type,
2446 : TALLOC_CTX *mem_ctx)
2447 : {
2448 2914230 : VFS_FIND(sys_acl_get_fd);
2449 1931932 : return handle->fns->sys_acl_get_fd_fn(handle, fsp, type, mem_ctx);
2450 : }
2451 :
2452 795043 : int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2453 : struct files_struct *fsp,
2454 : TALLOC_CTX *mem_ctx,
2455 : char **blob_description,
2456 : DATA_BLOB *blob)
2457 : {
2458 804859 : VFS_FIND(sys_acl_blob_get_fd);
2459 795043 : return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2460 : }
2461 :
2462 328513 : int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2463 : struct files_struct *fsp,
2464 : SMB_ACL_TYPE_T type,
2465 : SMB_ACL_T theacl)
2466 : {
2467 401791 : VFS_FIND(sys_acl_set_fd);
2468 328513 : return handle->fns->sys_acl_set_fd_fn(handle, fsp, type, theacl);
2469 : }
2470 :
2471 321 : int smb_vfs_call_sys_acl_delete_def_fd(struct vfs_handle_struct *handle,
2472 : struct files_struct *fsp)
2473 : {
2474 788 : VFS_FIND(sys_acl_delete_def_fd);
2475 321 : return handle->fns->sys_acl_delete_def_fd_fn(handle, fsp);
2476 : }
2477 :
2478 : struct smb_vfs_call_getxattrat_state {
2479 : files_struct *dir_fsp;
2480 : ssize_t (*recv_fn)(struct tevent_req *req,
2481 : struct vfs_aio_state *aio_state,
2482 : TALLOC_CTX *mem_ctx,
2483 : uint8_t **xattr_value);
2484 : ssize_t retval;
2485 : uint8_t *xattr_value;
2486 : struct vfs_aio_state aio_state;
2487 : };
2488 :
2489 : static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2490 :
2491 20137 : struct tevent_req *smb_vfs_call_getxattrat_send(
2492 : TALLOC_CTX *mem_ctx,
2493 : struct tevent_context *ev,
2494 : struct vfs_handle_struct *handle,
2495 : files_struct *dir_fsp,
2496 : const struct smb_filename *smb_fname,
2497 : const char *xattr_name,
2498 : size_t alloc_hint)
2499 : {
2500 20137 : struct tevent_req *req = NULL;
2501 20137 : struct smb_vfs_call_getxattrat_state *state = NULL;
2502 20137 : struct tevent_req *subreq = NULL;
2503 :
2504 20137 : req = tevent_req_create(mem_ctx, &state,
2505 : struct smb_vfs_call_getxattrat_state);
2506 20137 : if (req == NULL) {
2507 0 : return NULL;
2508 : }
2509 :
2510 40302 : VFS_FIND(getxattrat_send);
2511 :
2512 20137 : *state = (struct smb_vfs_call_getxattrat_state) {
2513 : .dir_fsp = dir_fsp,
2514 20137 : .recv_fn = handle->fns->getxattrat_recv_fn,
2515 : };
2516 :
2517 20137 : subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2518 : ev,
2519 : handle,
2520 : dir_fsp,
2521 : smb_fname,
2522 : xattr_name,
2523 : alloc_hint);
2524 20137 : if (tevent_req_nomem(subreq, req)) {
2525 0 : return tevent_req_post(req, ev);
2526 : }
2527 20137 : tevent_req_defer_callback(req, ev);
2528 :
2529 20137 : tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2530 20137 : return req;
2531 : }
2532 :
2533 20137 : static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2534 : {
2535 20137 : struct tevent_req *req = tevent_req_callback_data(
2536 : subreq, struct tevent_req);
2537 20137 : struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2538 : req, struct smb_vfs_call_getxattrat_state);
2539 0 : bool ok;
2540 :
2541 : /*
2542 : * Make sure we run as the user again
2543 : */
2544 20137 : ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2545 20137 : SMB_ASSERT(ok);
2546 :
2547 20137 : state->retval = state->recv_fn(subreq,
2548 : &state->aio_state,
2549 : state,
2550 : &state->xattr_value);
2551 20137 : TALLOC_FREE(subreq);
2552 20137 : if (state->retval == -1) {
2553 119 : tevent_req_error(req, state->aio_state.error);
2554 119 : return;
2555 : }
2556 :
2557 20018 : tevent_req_done(req);
2558 : }
2559 :
2560 20137 : ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2561 : struct vfs_aio_state *aio_state,
2562 : TALLOC_CTX *mem_ctx,
2563 : uint8_t **xattr_value)
2564 : {
2565 20137 : struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2566 : req, struct smb_vfs_call_getxattrat_state);
2567 0 : size_t xattr_size;
2568 :
2569 20137 : if (tevent_req_is_unix_error(req, &aio_state->error)) {
2570 119 : tevent_req_received(req);
2571 119 : return -1;
2572 : }
2573 :
2574 20018 : *aio_state = state->aio_state;
2575 20018 : xattr_size = state->retval;
2576 20018 : if (xattr_value != NULL) {
2577 20018 : *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2578 : }
2579 :
2580 20018 : tevent_req_received(req);
2581 20018 : return xattr_size;
2582 : }
2583 :
2584 25706799 : ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2585 : struct files_struct *fsp, const char *name,
2586 : void *value, size_t size)
2587 : {
2588 29002665 : VFS_FIND(fgetxattr);
2589 25706799 : return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2590 : }
2591 :
2592 1482583 : ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2593 : struct files_struct *fsp, char *list,
2594 : size_t size)
2595 : {
2596 2601655 : VFS_FIND(flistxattr);
2597 1482583 : return handle->fns->flistxattr_fn(handle, fsp, list, size);
2598 : }
2599 :
2600 4485 : int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2601 : struct files_struct *fsp, const char *name)
2602 : {
2603 7007 : VFS_FIND(fremovexattr);
2604 4485 : return handle->fns->fremovexattr_fn(handle, fsp, name);
2605 : }
2606 :
2607 1121880 : int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2608 : struct files_struct *fsp, const char *name,
2609 : const void *value, size_t size, int flags)
2610 : {
2611 1592206 : VFS_FIND(fsetxattr);
2612 1121880 : return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2613 : }
2614 :
2615 195 : bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2616 : struct files_struct *fsp)
2617 : {
2618 540 : VFS_FIND(aio_force);
2619 195 : return handle->fns->aio_force_fn(handle, fsp);
2620 : }
2621 :
2622 1318 : NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2623 : struct files_struct *fsp,
2624 : TALLOC_CTX *mem_ctx,
2625 : DATA_BLOB *cookie)
2626 : {
2627 3670 : VFS_FIND(durable_cookie);
2628 1318 : return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2629 : }
2630 :
2631 392 : NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2632 : struct files_struct *fsp,
2633 : const DATA_BLOB old_cookie,
2634 : TALLOC_CTX *mem_ctx,
2635 : DATA_BLOB *new_cookie)
2636 : {
2637 1106 : VFS_FIND(durable_disconnect);
2638 392 : return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2639 : mem_ctx, new_cookie);
2640 : }
2641 :
2642 378 : NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2643 : struct smb_request *smb1req,
2644 : struct smbXsrv_open *op,
2645 : const DATA_BLOB old_cookie,
2646 : TALLOC_CTX *mem_ctx,
2647 : struct files_struct **fsp,
2648 : DATA_BLOB *new_cookie)
2649 : {
2650 1050 : VFS_FIND(durable_reconnect);
2651 378 : return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2652 : old_cookie, mem_ctx, fsp,
2653 : new_cookie);
2654 : }
2655 :
2656 1735884 : NTSTATUS smb_vfs_call_freaddir_attr(struct vfs_handle_struct *handle,
2657 : struct files_struct *fsp,
2658 : TALLOC_CTX *mem_ctx,
2659 : struct readdir_attr_data **attr_data)
2660 : {
2661 5623777 : VFS_FIND(freaddir_attr);
2662 1735884 : return handle->fns->freaddir_attr_fn(handle,
2663 : fsp,
2664 : mem_ctx,
2665 : attr_data);
2666 : }
2667 :
2668 16496 : bool smb_vfs_call_lock(struct vfs_handle_struct *handle,
2669 : struct files_struct *fsp, int op, off_t offset,
2670 : off_t count, int type)
2671 : {
2672 37806 : VFS_FIND(lock);
2673 16496 : return handle->fns->lock_fn(handle, fsp, op, offset, count, type);
2674 : }
2675 :
2676 465849 : bool smb_vfs_call_getlock(struct vfs_handle_struct *handle,
2677 : struct files_struct *fsp, off_t *poffset,
2678 : off_t *pcount, int *ptype, pid_t *ppid)
2679 : {
2680 1160685 : VFS_FIND(getlock);
2681 465849 : return handle->fns->getlock_fn(handle, fsp, poffset, pcount, ptype,
2682 : ppid);
2683 : }
2684 :
2685 17121 : NTSTATUS smb_vfs_call_brl_lock_windows(struct vfs_handle_struct *handle,
2686 : struct byte_range_lock *br_lck,
2687 : struct lock_struct *plock)
2688 : {
2689 40381 : VFS_FIND(brl_lock_windows);
2690 17121 : return handle->fns->brl_lock_windows_fn(handle, br_lck, plock);
2691 : }
2692 :
2693 8447 : bool smb_vfs_call_brl_unlock_windows(struct vfs_handle_struct *handle,
2694 : struct byte_range_lock *br_lck,
2695 : const struct lock_struct *plock)
2696 : {
2697 20079 : VFS_FIND(brl_unlock_windows);
2698 8447 : return handle->fns->brl_unlock_windows_fn(handle, br_lck, plock);
2699 : }
|