source: vendor/3.5.0/source3/modules/onefs_open.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 59.8 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 *
4 * This file began with some code from source3/smbd/open.c and has been
5 * modified it work with ifs_createfile.
6 *
7 * ifs_createfile is a CIFS-specific syscall for opening/files and
8 * directories. It adds support for:
9 * - Full in-kernel access checks using a windows access_mask
10 * - Cluster-coherent share mode locks
11 * - Cluster-coherent oplocks
12 * - Streams
13 * - Setting security descriptors at create time
14 * - Setting dos_attributes at create time
15 *
16 * Copyright (C) Andrew Tridgell 1992-1998
17 * Copyright (C) Jeremy Allison 2001-2004
18 * Copyright (C) Volker Lendecke 2005
19 * Copyright (C) Tim Prouty, 2008
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 3 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, see <http://www.gnu.org/licenses/>.
33 */
34
35#include "includes.h"
36#include "onefs.h"
37#include "onefs_config.h"
38#include "oplock_onefs.h"
39#include "smbd/globals.h"
40
41extern const struct generic_mapping file_generic_mapping;
42
43struct onefs_fsp_data {
44 uint64_t oplock_callback_id;
45};
46
47static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
48 struct smb_request *req,
49 struct smb_filename *smb_fname,
50 uint32_t access_mask,
51 uint32_t share_access,
52 uint32_t create_disposition,
53 uint32_t create_options,
54 uint32_t file_attributes,
55 uint32_t oplock_request,
56 uint64_t allocation_size,
57 struct security_descriptor *sd,
58 struct ea_list *ea_list,
59 files_struct **result,
60 int *pinfo,
61 struct onefs_fsp_data *fsp_data);
62
63/****************************************************************************
64 Open a file.
65****************************************************************************/
66
67static NTSTATUS onefs_open_file(files_struct *fsp,
68 connection_struct *conn,
69 struct smb_request *req,
70 const char *parent_dir,
71 struct smb_filename *smb_fname,
72 int flags,
73 mode_t unx_mode,
74 uint32 access_mask,
75 uint32 open_access_mask,
76 int oplock_request,
77 uint64 id,
78 uint32 share_access,
79 uint32 create_options,
80 uint32_t new_dos_attributes,
81 struct security_descriptor *sd,
82 int *granted_oplock)
83{
84 struct smb_filename *smb_fname_onefs = NULL;
85 NTSTATUS status = NT_STATUS_OK;
86 int accmode = (flags & O_ACCMODE);
87 int local_flags = flags;
88 bool file_existed = VALID_STAT(smb_fname->st);
89 const char *wild;
90 int base_fd = -1;
91
92 fsp->fh->fd = -1;
93 errno = EPERM;
94
95 /* Check permissions */
96
97 /*
98 * This code was changed after seeing a client open request
99 * containing the open mode of (DENY_WRITE/read-only) with
100 * the 'create if not exist' bit set. The previous code
101 * would fail to open the file read only on a read-only share
102 * as it was checking the flags parameter directly against O_RDONLY,
103 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
104 * JRA.
105 */
106
107 if (!CAN_WRITE(conn)) {
108 /* It's a read-only share - fail if we wanted to write. */
109 if(accmode != O_RDONLY) {
110 DEBUG(3, ("Permission denied opening %s\n",
111 smb_fname_str_dbg(smb_fname)));
112 return NT_STATUS_ACCESS_DENIED;
113 } else if(flags & O_CREAT) {
114 /* We don't want to write - but we must make sure that
115 O_CREAT doesn't create the file if we have write
116 access into the directory.
117 */
118 flags &= ~O_CREAT;
119 local_flags &= ~O_CREAT;
120 }
121 }
122
123 /*
124 * This little piece of insanity is inspired by the
125 * fact that an NT client can open a file for O_RDONLY,
126 * but set the create disposition to FILE_EXISTS_TRUNCATE.
127 * If the client *can* write to the file, then it expects to
128 * truncate the file, even though it is opening for readonly.
129 * Quicken uses this stupid trick in backup file creation...
130 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
131 * for helping track this one down. It didn't bite us in 2.0.x
132 * as we always opened files read-write in that release. JRA.
133 */
134
135 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
136 DEBUG(10,("onefs_open_file: truncate requested on read-only "
137 "open for file %s\n", smb_fname_str_dbg(smb_fname)));
138 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
139 }
140
141#if defined(O_NONBLOCK) && defined(S_ISFIFO)
142 /*
143 * We would block on opening a FIFO with no one else on the
144 * other end. Do what we used to do and add O_NONBLOCK to the
145 * open flags. JRA.
146 */
147
148 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
149 local_flags |= O_NONBLOCK;
150 }
151#endif
152
153 /* Don't create files with Microsoft wildcard characters. */
154 if (fsp->base_fsp) {
155 /*
156 * wildcard characters are allowed in stream names
157 * only test the basefilename
158 */
159 wild = fsp->base_fsp->fsp_name->base_name;
160 } else {
161 wild = smb_fname->base_name;
162 }
163 if ((local_flags & O_CREAT) && !file_existed &&
164 ms_has_wild(wild)) {
165 /*
166 * XXX: may need to remvoe this return...
167 *
168 * We dont think this check needs to exist. All it does is
169 * block creating files with Microsoft wildcards, which is
170 * fine if the creation originated from NFS or locally and
171 * then was copied via Samba.
172 */
173 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
174 smb_fname_str_dbg(smb_fname)));
175 return NT_STATUS_OBJECT_NAME_INVALID;
176 }
177
178 /* Actually do the open */
179
180#ifdef O_NOFOLLOW
181 /*
182 * Never follow symlinks on a POSIX client. The
183 * client should be doing this.
184 */
185
186 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
187 flags |= O_NOFOLLOW;
188 }
189#endif
190 /* Setup a onefs-style smb_fname struct. */
191 status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
192 &smb_fname_onefs);
193 if (!NT_STATUS_IS_OK(status)) {
194 return status;
195 }
196
197 /* If it's a stream pass in the base_fd */
198 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
199 is_ntfs_stream_smb_fname(smb_fname_onefs)) {
200 SMB_ASSERT(fsp->base_fsp);
201
202 DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
203 smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
204 smb_fname_onefs->stream_name));
205
206 base_fd = fsp->base_fsp->fh->fd;
207 }
208
209 fsp->fh->fd = onefs_sys_create_file(conn,
210 base_fd,
211 smb_fname_onefs->stream_name != NULL ?
212 smb_fname_onefs->stream_name :
213 smb_fname_onefs->base_name,
214 access_mask,
215 open_access_mask,
216 share_access,
217 create_options,
218 flags,
219 unx_mode,
220 oplock_request,
221 id,
222 sd,
223 new_dos_attributes,
224 granted_oplock);
225 TALLOC_FREE(smb_fname_onefs);
226
227 if (fsp->fh->fd == -1) {
228 if (errno == EMFILE) {
229 static time_t last_warned = 0L;
230
231 if (time((time_t *) NULL) > last_warned) {
232 DEBUG(0, ("Too many open files, unable "
233 "to open more! smbd's max "
234 "open files = %d, also check "
235 "sysctl kern.maxfiles and "
236 "sysctl kern.maxfilesperproc\n",
237 lp_max_open_files()));
238 last_warned = time((time_t *) NULL);
239 }
240 }
241
242 status = map_nt_error_from_unix(errno);
243 DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
244 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
245 strerror(errno), local_flags, flags));
246 return status;
247 }
248
249 if ((local_flags & O_CREAT) && !file_existed) {
250
251 /* Inherit the ACL if required */
252 if (lp_inherit_perms(SNUM(conn))) {
253 inherit_access_posix_acl(conn, parent_dir,
254 smb_fname->base_name, unx_mode);
255 }
256
257 /* Change the owner if required. */
258 if (lp_inherit_owner(SNUM(conn))) {
259 change_file_owner_to_parent(conn, parent_dir,
260 fsp);
261 }
262
263 notify_fname(conn, NOTIFY_ACTION_ADDED,
264 FILE_NOTIFY_CHANGE_FILE_NAME, smb_fname->base_name);
265 }
266
267 if (!file_existed) {
268 int ret;
269
270 if (fsp->fh->fd == -1) {
271 ret = SMB_VFS_STAT(conn, smb_fname);
272 } else {
273 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
274 /* If we have an fd, this stat should succeed. */
275 if (ret == -1) {
276 DEBUG(0, ("Error doing fstat on open file %s "
277 "(%s)\n",
278 smb_fname_str_dbg(smb_fname),
279 strerror(errno) ));
280 }
281 }
282
283 /* For a non-io open, this stat failing means file not found. JRA */
284 if (ret == -1) {
285 status = map_nt_error_from_unix(errno);
286 fd_close(fsp);
287 return status;
288 }
289 }
290
291 /*
292 * POSIX allows read-only opens of directories. We don't
293 * want to do this (we use a different code path for this)
294 * so catch a directory open and return an EISDIR. JRA.
295 */
296
297 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
298 fd_close(fsp);
299 errno = EISDIR;
300 return NT_STATUS_FILE_IS_A_DIRECTORY;
301 }
302
303 fsp->mode = smb_fname->st.st_ex_mode;
304 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
305 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
306 fsp->file_pid = req ? req->smbpid : 0;
307 fsp->can_lock = True;
308 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
309 if (!CAN_WRITE(conn)) {
310 fsp->can_write = False;
311 } else {
312 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
313 True : False;
314 }
315 fsp->print_file = False;
316 fsp->modified = False;
317 fsp->sent_oplock_break = NO_BREAK_SENT;
318 fsp->is_directory = False;
319 if (conn->aio_write_behind_list &&
320 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
321 conn->case_sensitive)) {
322 fsp->aio_write_behind = True;
323 }
324
325 fsp->wcp = NULL; /* Write cache pointer. */
326
327 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
328 conn->server_info->unix_name,
329 smb_fname_str_dbg(smb_fname),
330 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
331 conn->num_files_open));
332
333 errno = 0;
334 return NT_STATUS_OK;
335}
336
337/****************************************************************************
338 Handle the 1 second delay in returning a SHARING_VIOLATION error.
339****************************************************************************/
340
341static void defer_open(struct share_mode_lock *lck,
342 struct timeval request_time,
343 struct timeval timeout,
344 struct smb_request *req,
345 struct deferred_open_record *state)
346{
347 int i;
348
349 /* Paranoia check */
350
351 for (i=0; i<lck->num_share_modes; i++) {
352 struct share_mode_entry *e = &lck->share_modes[i];
353
354 if (!is_deferred_open_entry(e)) {
355 continue;
356 }
357
358 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
359 DEBUG(0, ("Trying to defer an already deferred "
360 "request: mid=%d, exiting\n", req->mid));
361 exit_server("attempt to defer a deferred request");
362 }
363 }
364
365 /* End paranoia check */
366
367 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
368 "open entry for mid %u\n",
369 (unsigned int)request_time.tv_sec,
370 (unsigned int)request_time.tv_usec,
371 (unsigned int)req->mid));
372
373 if (!push_deferred_smb_message(req, request_time, timeout,
374 (char *)state, sizeof(*state))) {
375 exit_server("push_deferred_smb_message failed");
376 }
377 add_deferred_open(lck, req->mid, request_time, state->id);
378}
379
380static void schedule_defer_open(struct share_mode_lock *lck,
381 struct timeval request_time,
382 struct smb_request *req)
383{
384 struct deferred_open_record state;
385
386 /* This is a relative time, added to the absolute
387 request_time value to get the absolute timeout time.
388 Note that if this is the second or greater time we enter
389 this codepath for this particular request mid then
390 request_time is left as the absolute time of the *first*
391 time this request mid was processed. This is what allows
392 the request to eventually time out. */
393
394 struct timeval timeout;
395
396 /* Normally the smbd we asked should respond within
397 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
398 * the client did, give twice the timeout as a safety
399 * measure here in case the other smbd is stuck
400 * somewhere else. */
401
402 /*
403 * On OneFS, the kernel will always send an oplock_revoked message
404 * before this timeout is hit.
405 */
406 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
407
408 /* Nothing actually uses state.delayed_for_oplocks
409 but it's handy to differentiate in debug messages
410 between a 30 second delay due to oplock break, and
411 a 1 second delay for share mode conflicts. */
412
413 state.delayed_for_oplocks = True;
414 state.failed = false;
415 state.id = lck->id;
416
417 if (!request_timed_out(request_time, timeout)) {
418 defer_open(lck, request_time, timeout, req, &state);
419 } else {
420 /* A delayed-for-oplocks deferred open timing out should only
421 * happen if there is a bug or extreme load, since we set the
422 * timeout to 300 seconds. */
423 DEBUG(0, ("Deferred open timeout! request_time=%d.%d, "
424 "mid=%d\n", request_time.tv_sec, request_time.tv_usec,
425 req->mid));
426 }
427}
428
429/****************************************************************************
430 Open a file with a share mode. Passed in an already created files_struct.
431****************************************************************************/
432NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
433 struct smb_request *req,
434 struct smb_filename *smb_fname,
435 uint32 access_mask,
436 uint32 share_access,
437 uint32 create_disposition,
438 uint32 create_options,
439 uint32 new_dos_attributes,
440 int oplock_request,
441 struct security_descriptor *sd,
442 files_struct *fsp,
443 int *pinfo,
444 struct onefs_fsp_data *fsp_data)
445{
446 int flags=0;
447 int flags2=0;
448 bool file_existed = VALID_STAT(smb_fname->st);
449 bool def_acl = False;
450 bool posix_open = False;
451 bool new_file_created = False;
452 bool clear_ads = False;
453 struct file_id id;
454 mode_t new_unx_mode = (mode_t)0;
455 mode_t unx_mode = (mode_t)0;
456 int info;
457 uint32 existing_dos_attributes = 0;
458 struct pending_message_list *pml = NULL;
459 struct timeval request_time = timeval_zero();
460 struct share_mode_lock *lck = NULL;
461 uint32 open_access_mask = access_mask;
462 NTSTATUS status;
463 int ret_flock;
464 char *parent_dir;
465 int granted_oplock;
466 uint64_t oplock_callback_id = 0;
467 uint32 createfile_attributes = 0;
468
469 ZERO_STRUCT(id);
470
471 if (conn->printer) {
472 /*
473 * Printers are handled completely differently.
474 * Most of the passed parameters are ignored.
475 */
476
477 if (pinfo) {
478 *pinfo = FILE_WAS_CREATED;
479 }
480
481 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
482 smb_fname_str_dbg(smb_fname)));
483
484 return print_fsp_open(req, conn, smb_fname->base_name,
485 req->vuid, fsp);
486 }
487
488 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
489 NULL)) {
490 return NT_STATUS_NO_MEMORY;
491 }
492
493 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
494 posix_open = True;
495 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
496 new_dos_attributes = 0;
497 } else {
498 /* We add aARCH to this as this mode is only used if the file is
499 * created new. */
500 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
501 smb_fname, parent_dir);
502 }
503
504 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
505 "access_mask=0x%x share_access=0x%x "
506 "create_disposition = 0x%x create_options=0x%x "
507 "unix mode=0%o oplock_request=0x%x\n",
508 smb_fname_str_dbg(smb_fname), new_dos_attributes,
509 access_mask, share_access, create_disposition,
510 create_options, unx_mode, oplock_request));
511
512 /*
513 * Any non-stat-only open has the potential to contend oplocks, which
514 * means to avoid blocking in the kernel (which is unacceptable), the
515 * open must be deferred. In order to defer opens, req must not be
516 * NULL. The known cases of calling with a NULL req:
517 *
518 * 1. Open the base file of a stream: Always done stat-only
519 *
520 * 2. open_file_fchmod(), which is called from 3 places:
521 * A. try_chown: Posix acls only. Never called on onefs.
522 * B. set_ea_dos_attributes: Can't be called from onefs, because
523 * SMB_VFS_SETXATTR return ENOSYS.
524 * C. file_set_dos_mode: This would only happen if the "dos
525 * filemode" smb.conf parameter is set to yes. We ship with
526 * it off, but if a customer were to turn it on it would be
527 * bad.
528 */
529 if (req == NULL && !is_stat_open(access_mask) &&
530 !is_ntfs_stream_smb_fname(smb_fname)) {
531 smb_panic("NULL req on a non-stat-open!");
532 }
533
534 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
535 DEBUG(0, ("No smb request but not an internal only open!\n"));
536 return NT_STATUS_INTERNAL_ERROR;
537 }
538
539 /*
540 * Only non-internal opens can be deferred at all
541 */
542
543 if ((req != NULL)
544 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
545 struct deferred_open_record *state =
546 (struct deferred_open_record *)pml->private_data.data;
547
548 /* Remember the absolute time of the original
549 request with this mid. We'll use it later to
550 see if this has timed out. */
551
552 request_time = pml->request_time;
553
554 /* Remove the deferred open entry under lock. */
555 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
556 NULL);
557 if (lck == NULL) {
558 DEBUG(0, ("could not get share mode lock\n"));
559 } else {
560 del_deferred_open_entry(lck, req->mid);
561 TALLOC_FREE(lck);
562 }
563
564 /* Ensure we don't reprocess this message. */
565 remove_deferred_open_smb_message(req->mid);
566
567 /*
568 * When receiving a semlock_async_failure message, the
569 * deferred open will be marked as "failed". Returning
570 * INTERNAL_ERROR.
571 */
572 if (state->failed) {
573 DEBUG(0, ("onefs_open_file_ntcreate: "
574 "semlock_async_failure detected!\n"));
575 return NT_STATUS_INTERNAL_ERROR;
576 }
577 }
578
579 status = check_name(conn, smb_fname->base_name);
580 if (!NT_STATUS_IS_OK(status)) {
581 return status;
582 }
583
584 if (!posix_open) {
585 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
586 if (file_existed) {
587 existing_dos_attributes = dos_mode(conn, smb_fname);
588 }
589 }
590
591 /* Setup dos_attributes to be set by ifs_createfile */
592 if (lp_store_dos_attributes(SNUM(conn))) {
593 createfile_attributes = (new_dos_attributes | aARCH) &
594 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
595 }
596
597 /* Ignore oplock requests if oplocks are disabled. */
598 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
599 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
600 /* Mask off everything except the private Samba bits. */
601 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
602 }
603
604 /* this is for OS/2 long file names - say we don't support them */
605 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
606 /* OS/2 Workplace shell fix may be main code stream in a later
607 * release. */
608 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
609 "not supported.\n"));
610 if (use_nt_status()) {
611 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
612 }
613 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
614 }
615
616 switch( create_disposition ) {
617 /*
618 * Currently we're using FILE_SUPERSEDE as the same as
619 * FILE_OVERWRITE_IF but they really are
620 * different. FILE_SUPERSEDE deletes an existing file
621 * (requiring delete access) then recreates it.
622 */
623 case FILE_SUPERSEDE:
624 /**
625 * @todo: Clear all file attributes?
626 * http://www.osronline.com/article.cfm?article=302
627 * create if not exist, trunc if exist
628 *
629 * If file exists replace/overwrite. If file doesn't
630 * exist create.
631 */
632 flags2 |= (O_CREAT | O_TRUNC);
633 clear_ads = true;
634 break;
635
636 case FILE_OVERWRITE_IF:
637 /* If file exists replace/overwrite. If file doesn't
638 * exist create. */
639 flags2 |= (O_CREAT | O_TRUNC);
640 clear_ads = true;
641 break;
642
643 case FILE_OPEN:
644 /* If file exists open. If file doesn't exist error. */
645 if (!file_existed) {
646 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
647 "requested for file %s and file "
648 "doesn't exist.\n",
649 smb_fname_str_dbg(smb_fname)));
650 errno = ENOENT;
651 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
652 }
653 break;
654
655 case FILE_OVERWRITE:
656 /* If file exists overwrite. If file doesn't exist
657 * error. */
658 if (!file_existed) {
659 DEBUG(5, ("onefs_open_file_ntcreate: "
660 "FILE_OVERWRITE requested for file "
661 "%s and file doesn't exist.\n",
662 smb_fname_str_dbg(smb_fname)));
663 errno = ENOENT;
664 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
665 }
666 flags2 |= O_TRUNC;
667 clear_ads = true;
668 break;
669
670 case FILE_CREATE:
671 /* If file exists error. If file doesn't exist
672 * create. */
673 if (file_existed) {
674 DEBUG(5, ("onefs_open_file_ntcreate: "
675 "FILE_CREATE requested for file %s "
676 "and file already exists.\n",
677 smb_fname_str_dbg(smb_fname)));
678 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
679 errno = EISDIR;
680 } else {
681 errno = EEXIST;
682 }
683 return map_nt_error_from_unix(errno);
684 }
685 flags2 |= (O_CREAT|O_EXCL);
686 break;
687
688 case FILE_OPEN_IF:
689 /* If file exists open. If file doesn't exist
690 * create. */
691 flags2 |= O_CREAT;
692 break;
693
694 default:
695 return NT_STATUS_INVALID_PARAMETER;
696 }
697
698 /* Match attributes on file exists and overwrite. */
699 if (!posix_open && file_existed &&
700 ((create_disposition == FILE_OVERWRITE) ||
701 (create_disposition == FILE_OVERWRITE_IF))) {
702 if (!open_match_attributes(conn, existing_dos_attributes,
703 new_dos_attributes,
704 smb_fname->st.st_ex_mode,
705 unx_mode, &new_unx_mode)) {
706 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
707 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
708 smb_fname_str_dbg(smb_fname),
709 existing_dos_attributes,
710 new_dos_attributes,
711 (unsigned int)smb_fname->st.st_ex_mode,
712 (unsigned int)unx_mode ));
713 errno = EACCES;
714 return NT_STATUS_ACCESS_DENIED;
715 }
716 }
717
718 /*
719 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
720 * access_mask, but leave the MAA for the actual open in
721 * open_access_mask.
722 */
723 open_access_mask = access_mask;
724 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
725 access_mask |= FILE_GENERIC_ALL;
726 }
727
728 /* Convert GENERIC bits to specific bits. */
729 se_map_generic(&access_mask, &file_generic_mapping);
730 se_map_generic(&open_access_mask, &file_generic_mapping);
731
732 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
733 /* This will cause oplock breaks. */
734 open_access_mask |= FILE_WRITE_DATA;
735 }
736
737 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
738 "open_access_mask=%#x, access_mask=0x%x\n",
739 smb_fname_str_dbg(smb_fname), open_access_mask,
740 access_mask));
741
742 /*
743 * Note that we ignore the append flag as append does not
744 * mean the same thing under DOS and Unix.
745 */
746
747 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
748 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
749
750 /*
751 * DENY_DOS opens are always underlying read-write on the
752 * file handle, no matter what the requested access mask
753 * says. Stock samba just sets the flags, but since
754 * ifs_createfile uses the access_mask, it must be updated as
755 * well. This allows BASE-DENY* to pass.
756 */
757 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
758
759 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
760 "Adding O_RDWR to flags "
761 "(0x%x) and some READ bits to "
762 "open_access_mask (0x%x)\n",
763 flags, open_access_mask));
764
765 flags = O_RDWR;
766 open_access_mask |= (FILE_READ_ATTRIBUTES |
767 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
768
769 } else if (access_mask & (FILE_READ_ATTRIBUTES |
770 FILE_READ_DATA |
771 FILE_READ_EA |
772 FILE_EXECUTE)) {
773 flags = O_RDWR;
774 } else {
775 flags = O_WRONLY;
776 }
777 } else {
778 flags = O_RDONLY;
779 }
780
781 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
782#if defined(O_SYNC)
783 if ((create_options & FILE_WRITE_THROUGH) &&
784 lp_strict_sync(SNUM(conn))) {
785 flags2 |= O_SYNC;
786 }
787#endif /* O_SYNC */
788
789 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
790 flags2 |= O_APPEND;
791 }
792
793 if (!posix_open && !CAN_WRITE(conn)) {
794 /*
795 * We should really return a permission denied error if either
796 * O_CREAT or O_TRUNC are set, but for compatibility with
797 * older versions of Samba we just AND them out.
798 */
799 flags2 &= ~(O_CREAT|O_TRUNC);
800
801 /* Deny DELETE_ACCESS explicitly if the share is read only. */
802 if (access_mask & DELETE_ACCESS) {
803 return map_nt_error_from_unix(EACCES);
804 }
805 }
806
807 /* Ensure we can't write on a read-only share or file. */
808 if (flags != O_RDONLY && file_existed &&
809 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
810 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
811 "for file %s on read only %s\n",
812 smb_fname_str_dbg(smb_fname),
813 !CAN_WRITE(conn) ? "share" : "file" ));
814 errno = EACCES;
815 return NT_STATUS_ACCESS_DENIED;
816 }
817
818 DEBUG(10, ("fsp = %p\n", fsp));
819
820 fsp->share_access = share_access;
821 fsp->fh->private_options = create_options;
822 fsp->access_mask = open_access_mask; /* We change this to the
823 * requested access_mask after
824 * the open is done. */
825 fsp->posix_open = posix_open;
826
827 /* Ensure no SAMBA_PRIVATE bits can be set. */
828 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
829
830 if (timeval_is_zero(&request_time)) {
831 request_time = fsp->open_time;
832 }
833
834 if (file_existed) {
835 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
836 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
837
838 lck = get_share_mode_lock(talloc_tos(), id,
839 conn->connectpath,
840 smb_fname, &old_write_time);
841
842 if (lck == NULL) {
843 DEBUG(0, ("Could not get share mode lock\n"));
844 return NT_STATUS_SHARING_VIOLATION;
845 }
846
847 if (lck->delete_on_close) {
848 /* DELETE_PENDING is not deferred for a second */
849 TALLOC_FREE(lck);
850 return NT_STATUS_DELETE_PENDING;
851 }
852 }
853
854 SMB_ASSERT(!file_existed || (lck != NULL));
855
856 /*
857 * Ensure we pay attention to default ACLs on directories. May be
858 * neccessary depending on ACL policies.
859 */
860 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
861 (def_acl = directory_has_default_acl(conn, parent_dir))) {
862 unx_mode = 0777;
863 }
864
865 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
866 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
867 (unsigned int)flags, (unsigned int)flags2,
868 (unsigned int)unx_mode, (unsigned int)access_mask,
869 (unsigned int)open_access_mask));
870
871 /*
872 * Since the open is guaranteed to be stat only if req == NULL, a
873 * callback record is only needed if req != NULL.
874 */
875 if (req) {
876 SMB_ASSERT(fsp_data);
877 oplock_callback_id = onefs_oplock_wait_record(req->mid);
878 if (oplock_callback_id == 0) {
879 return NT_STATUS_NO_MEMORY;
880 }
881 } else {
882 /*
883 * It is also already asserted it's either a stream or a
884 * stat-only open at this point.
885 */
886 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
887
888 /* The kernel and Samba's version of stat-only differs
889 * slightly: The kernel doesn't think its stat-only if we're
890 * truncating. We'd better have a req in order to defer the
891 * open. */
892 SMB_ASSERT(!((flags|flags2) & O_TRUNC));
893 }
894
895 /* Do the open. */
896 status = onefs_open_file(fsp,
897 conn,
898 req,
899 parent_dir,
900 smb_fname,
901 flags|flags2,
902 unx_mode,
903 access_mask,
904 open_access_mask,
905 fsp->oplock_type,
906 oplock_callback_id,
907 share_access,
908 create_options,
909 createfile_attributes,
910 sd,
911 &granted_oplock);
912
913 if (!NT_STATUS_IS_OK(status)) {
914
915 /* OneFS Oplock Handling */
916 if (errno == EINPROGRESS) {
917
918 /* If we get EINPROGRESS, the kernel will send us an
919 * asynchronous semlock event back. Ensure we can defer
920 * the open, by asserting req. */
921 SMB_ASSERT(req);
922
923 if (lck == NULL) {
924 /*
925 * We hit the race that when we did the stat
926 * on the file it did not exist, and someone
927 * has created it in between the stat and the
928 * open_file() call. Defer our open waiting,
929 * to break the oplock of the first opener.
930 */
931
932 struct timespec old_write_time;
933
934 DEBUG(3, ("Someone created file %s with an "
935 "oplock after we looked: Retrying\n",
936 smb_fname_str_dbg(smb_fname)));
937 /*
938 * We hit the race that when we did the stat
939 * on the file it did not exist, and someone
940 * has created it in between the stat and the
941 * open_file() call. Just retry immediately.
942 */
943 id = vfs_file_id_from_sbuf(conn,
944 &smb_fname->st);
945 if (!(lck = get_share_mode_lock(talloc_tos(),
946 id, conn->connectpath, smb_fname,
947 &old_write_time))) {
948 /*
949 * Emergency exit
950 */
951 DEBUG(0, ("onefs_open_file_ntcreate: "
952 "Could not get share mode "
953 "lock for %s\n",
954 smb_fname_str_dbg(smb_fname)));
955 status = NT_STATUS_SHARING_VIOLATION;
956
957 /* XXXZLK: This will cause us to get a
958 * semlock event when we aren't
959 * expecting one. */
960 goto cleanup_destroy;
961 }
962
963 schedule_defer_open(lck, request_time, req);
964 goto cleanup;
965 }
966 /* Waiting for an oplock */
967 DEBUG(5,("Async createfile because a client has an "
968 "oplock on %s\n",
969 smb_fname_str_dbg(smb_fname)));
970
971 SMB_ASSERT(req);
972 schedule_defer_open(lck, request_time, req);
973 goto cleanup;
974 }
975
976 /* Check for a sharing violation */
977 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
978 uint32 can_access_mask;
979 bool can_access = True;
980
981 /* If we raced on open we may not have a valid file_id
982 * or stat buf. Get them again. */
983 if (SMB_VFS_STAT(conn, fname, psbuf) == -1) {
984 DEBUG(0,("Error doing stat on file %s "
985 "(%s)\n", fname, strerror(errno)));
986 status = NT_STATUS_SHARING_VIOLATION;
987 goto cleanup_destroy;
988 }
989 id = vfs_file_id_from_sbuf(conn, psbuf);
990
991 /* Check if this can be done with the deny_dos and fcb
992 * calls. */
993
994 /* Try to find dup fsp if possible. */
995 if (create_options &
996 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
997 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
998
999 if (req == NULL) {
1000 DEBUG(0, ("DOS open without an SMB "
1001 "request!\n"));
1002 status = NT_STATUS_INTERNAL_ERROR;
1003 goto cleanup_destroy;
1004 }
1005
1006 /* Use the client requested access mask here,
1007 * not the one we open with. */
1008 status = fcb_or_dos_open(req,
1009 conn,
1010 fsp,
1011 smb_fname,
1012 id,
1013 req->smbpid,
1014 req->vuid,
1015 access_mask,
1016 share_access,
1017 create_options);
1018
1019 if (NT_STATUS_IS_OK(status)) {
1020 if (pinfo) {
1021 *pinfo = FILE_WAS_OPENED;
1022 }
1023 status = NT_STATUS_OK;
1024 goto cleanup;
1025 }
1026 }
1027
1028 /*
1029 * This next line is a subtlety we need for
1030 * MS-Access. If a file open will fail due to share
1031 * permissions and also for security (access) reasons,
1032 * we need to return the access failed error, not the
1033 * share error. We can't open the file due to kernel
1034 * oplock deadlock (it's possible we failed above on
1035 * the open_mode_check()) so use a userspace check.
1036 */
1037
1038 if (flags & O_RDWR) {
1039 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1040 } else if (flags & O_WRONLY) {
1041 can_access_mask = FILE_WRITE_DATA;
1042 } else {
1043 can_access_mask = FILE_READ_DATA;
1044 }
1045
1046 if (((can_access_mask & FILE_WRITE_DATA) &&
1047 !CAN_WRITE(conn)) ||
1048 !can_access_file_data(conn, smb_fname,
1049 can_access_mask)) {
1050 can_access = False;
1051 }
1052
1053 /*
1054 * If we're returning a share violation, ensure we
1055 * cope with the braindead 1 second delay.
1056 */
1057 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1058 lp_defer_sharing_violations()) {
1059 struct timeval timeout;
1060 struct deferred_open_record state;
1061 int timeout_usecs;
1062
1063 /* this is a hack to speed up torture tests
1064 in 'make test' */
1065 timeout_usecs = lp_parm_int(SNUM(conn),
1066 "smbd","sharedelay",
1067 SHARING_VIOLATION_USEC_WAIT);
1068
1069 /* This is a relative time, added to the
1070 absolute request_time value to get the
1071 absolute timeout time. Note that if this
1072 is the second or greater time we enter this
1073 codepath for this particular request mid
1074 then request_time is left as the absolute
1075 time of the *first* time this request mid
1076 was processed. This is what allows the
1077 request to eventually time out. */
1078
1079 timeout = timeval_set(0, timeout_usecs);
1080
1081 /* Nothing actually uses
1082 state.delayed_for_oplocks but it's handy to
1083 differentiate in debug messages between a
1084 30 second delay due to oplock break, and a
1085 1 second delay for share mode conflicts. */
1086
1087 state.delayed_for_oplocks = False;
1088 state.id = id;
1089 state.failed = false;
1090
1091 /*
1092 * We hit the race that when we did the stat
1093 * on the file it did not exist, and someone
1094 * has created it in between the stat and the
1095 * open_file() call. Retrieve the share_mode
1096 * lock on the newly opened file so we can
1097 * defer our request.
1098 */
1099 if (lck == NULL) {
1100 struct timespec old_write_time;
1101 old_write_time = get_mtimespec(psbuf);
1102
1103 lck = get_share_mode_lock(talloc_tos(),
1104 id, conn->connectpath, fname,
1105 &old_write_time);
1106 if (lck == NULL) {
1107 DEBUG(0,
1108 ("onefs_open_file_ntcreate:"
1109 " Could not get share "
1110 "mode lock for %s\n",
1111 fname));
1112 /* This will cause us to return
1113 * immediately skipping the
1114 * the 1 second delay, which
1115 * isn't a big deal */
1116 status = NT_STATUS_SHARING_VIOLATION;
1117 goto cleanup_destroy;
1118 }
1119 }
1120
1121 if ((req != NULL) &&
1122 !request_timed_out(request_time, timeout))
1123 {
1124 defer_open(lck, request_time, timeout,
1125 req, &state);
1126 }
1127 }
1128
1129 if (can_access) {
1130 /*
1131 * We have detected a sharing violation here
1132 * so return the correct error code
1133 */
1134 status = NT_STATUS_SHARING_VIOLATION;
1135 } else {
1136 status = NT_STATUS_ACCESS_DENIED;
1137 }
1138
1139 goto cleanup_destroy;
1140 }
1141
1142 /*
1143 * Normal error, for example EACCES
1144 */
1145 cleanup_destroy:
1146 if (oplock_callback_id != 0) {
1147 destroy_onefs_callback_record(oplock_callback_id);
1148 }
1149 cleanup:
1150 TALLOC_FREE(lck);
1151 return status;
1152 }
1153
1154 fsp->oplock_type = granted_oplock;
1155
1156 if (oplock_callback_id != 0) {
1157 onefs_set_oplock_callback(oplock_callback_id, fsp);
1158 fsp_data->oplock_callback_id = oplock_callback_id;
1159 } else {
1160 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1161 }
1162
1163 if (!file_existed) {
1164 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1165 /*
1166 * Deal with the race condition where two smbd's detect the
1167 * file doesn't exist and do the create at the same time. One
1168 * of them will win and set a share mode, the other (ie. this
1169 * one) should check if the requested share mode for this
1170 * create is allowed.
1171 */
1172
1173 /*
1174 * Now the file exists and fsp is successfully opened,
1175 * fsp->file_id is valid and should replace the
1176 * dev=0, inode=0 from a non existent file. Spotted by
1177 * Nadav Danieli <nadavd@exanet.com>. JRA.
1178 */
1179
1180 id = fsp->file_id;
1181
1182 lck = get_share_mode_lock(talloc_tos(), id,
1183 conn->connectpath,
1184 smb_fname, &old_write_time);
1185
1186 if (lck == NULL) {
1187 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1188 "share mode lock for %s\n",
1189 smb_fname_str_dbg(smb_fname)));
1190 fd_close(fsp);
1191 return NT_STATUS_SHARING_VIOLATION;
1192 }
1193
1194 if (lck->delete_on_close) {
1195 status = NT_STATUS_DELETE_PENDING;
1196 }
1197
1198 if (!NT_STATUS_IS_OK(status)) {
1199 struct deferred_open_record state;
1200
1201 fd_close(fsp);
1202
1203 state.delayed_for_oplocks = False;
1204 state.id = id;
1205
1206 /* Do it all over again immediately. In the second
1207 * round we will find that the file existed and handle
1208 * the DELETE_PENDING and FCB cases correctly. No need
1209 * to duplicate the code here. Essentially this is a
1210 * "goto top of this function", but don't tell
1211 * anybody... */
1212
1213 if (req != NULL) {
1214 defer_open(lck, request_time, timeval_zero(),
1215 req, &state);
1216 }
1217 TALLOC_FREE(lck);
1218 return status;
1219 }
1220
1221 /*
1222 * We exit this block with the share entry *locked*.....
1223 */
1224
1225 }
1226
1227 SMB_ASSERT(lck != NULL);
1228
1229 /* Delete streams if create_disposition requires it */
1230 if (file_existed && clear_ads &&
1231 !is_ntfs_stream_smb_fname(smb_fname)) {
1232 status = delete_all_streams(conn, smb_fname->base_name);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 TALLOC_FREE(lck);
1235 fd_close(fsp);
1236 return status;
1237 }
1238 }
1239
1240 /* note that we ignore failure for the following. It is
1241 basically a hack for NFS, and NFS will never set one of
1242 these only read them. Nobody but Samba can ever set a deny
1243 mode and we have already checked our more authoritative
1244 locking database for permission to set this deny mode. If
1245 the kernel refuses the operations then the kernel is wrong.
1246 note that GPFS supports it as well - jmcd */
1247
1248 if (fsp->fh->fd != -1) {
1249 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
1250 if(ret_flock == -1 ){
1251
1252 TALLOC_FREE(lck);
1253 fd_close(fsp);
1254 return NT_STATUS_SHARING_VIOLATION;
1255 }
1256 }
1257
1258 /*
1259 * At this point onwards, we can guarentee that the share entry
1260 * is locked, whether we created the file or not, and that the
1261 * deny mode is compatible with all current opens.
1262 */
1263
1264 /* Record the options we were opened with. */
1265 fsp->share_access = share_access;
1266 fsp->fh->private_options = create_options;
1267 /*
1268 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1269 */
1270 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1271
1272 if (file_existed) {
1273 /* stat opens on existing files don't get oplocks. */
1274 if (is_stat_open(open_access_mask)) {
1275 fsp->oplock_type = NO_OPLOCK;
1276 }
1277
1278 if (!(flags2 & O_TRUNC)) {
1279 info = FILE_WAS_OPENED;
1280 } else {
1281 info = FILE_WAS_OVERWRITTEN;
1282 }
1283 } else {
1284 info = FILE_WAS_CREATED;
1285 }
1286
1287 if (pinfo) {
1288 *pinfo = info;
1289 }
1290
1291 /*
1292 * Setup the oplock info in both the shared memory and
1293 * file structs.
1294 */
1295
1296 if ((fsp->oplock_type != NO_OPLOCK) &&
1297 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1298 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1299 /* Could not get the kernel oplock */
1300 fsp->oplock_type = NO_OPLOCK;
1301 }
1302 }
1303
1304 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1305 (!lp_level2_oplocks(SNUM(conn)) ||
1306 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1307
1308 DEBUG(5, ("Downgrading level2 oplock on open "
1309 "because level2 oplocks = off\n"));
1310
1311 release_file_oplock(fsp);
1312 }
1313
1314 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1315 info == FILE_WAS_SUPERSEDED) {
1316 new_file_created = True;
1317 }
1318
1319 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1320 fsp->oplock_type);
1321
1322 /* Handle strange delete on close create semantics. */
1323 if (create_options & FILE_DELETE_ON_CLOSE) {
1324 status = can_set_delete_on_close(fsp, new_dos_attributes);
1325
1326 if (!NT_STATUS_IS_OK(status)) {
1327 /* Remember to delete the mode we just added. */
1328 del_share_mode(lck, fsp);
1329 TALLOC_FREE(lck);
1330 fd_close(fsp);
1331 return status;
1332 }
1333 /* Note that here we set the *inital* delete on close flag,
1334 not the regular one. The magic gets handled in close. */
1335 fsp->initial_delete_on_close = True;
1336 }
1337
1338 /*
1339 * Take care of inherited ACLs on created files - if default ACL not
1340 * selected.
1341 * May be necessary depending on acl policies.
1342 */
1343 if (!posix_open && !file_existed && !def_acl &&
1344 !(VALID_STAT(smb_fname->st) &&
1345 (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
1346
1347 int saved_errno = errno; /* We might get ENOSYS in the next
1348 * call.. */
1349
1350 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1351 errno == ENOSYS) {
1352 errno = saved_errno; /* Ignore ENOSYS */
1353 }
1354
1355 } else if (new_unx_mode) {
1356
1357 int ret = -1;
1358
1359 /* Attributes need changing. File already existed. */
1360
1361 {
1362 int saved_errno = errno; /* We might get ENOSYS in the
1363 * next call.. */
1364 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1365
1366 if (ret == -1 && errno == ENOSYS) {
1367 errno = saved_errno; /* Ignore ENOSYS */
1368 } else {
1369 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1370 "attributes of file %s to 0%o\n",
1371 smb_fname_str_dbg(smb_fname),
1372 (unsigned int)new_unx_mode));
1373 ret = 0; /* Don't do the fchmod below. */
1374 }
1375 }
1376
1377 if ((ret == -1) &&
1378 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1379 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1380 "attributes of file %s to 0%o\n",
1381 smb_fname_str_dbg(smb_fname),
1382 (unsigned int)new_unx_mode));
1383 }
1384
1385 /* If this is a successful open, we must remove any deferred open
1386 * records. */
1387 if (req != NULL) {
1388 del_deferred_open_entry(lck, req->mid);
1389 }
1390 TALLOC_FREE(lck);
1391
1392 return NT_STATUS_OK;
1393}
1394
1395
1396/****************************************************************************
1397 Open a directory from an NT SMB call.
1398****************************************************************************/
1399static NTSTATUS onefs_open_directory(connection_struct *conn,
1400 struct smb_request *req,
1401 struct smb_filename *smb_dname,
1402 uint32 access_mask,
1403 uint32 share_access,
1404 uint32 create_disposition,
1405 uint32 create_options,
1406 uint32 file_attributes,
1407 struct security_descriptor *sd,
1408 files_struct **result,
1409 int *pinfo)
1410{
1411 files_struct *fsp = NULL;
1412 struct share_mode_lock *lck = NULL;
1413 NTSTATUS status;
1414 struct timespec mtimespec;
1415 int info = 0;
1416 char *parent_dir;
1417 bool posix_open = false;
1418 uint32 create_flags = 0;
1419 uint32 mode = lp_dir_mask(SNUM(conn));
1420
1421 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1422 "access_mask = 0x%x, "
1423 "share_access = 0x%x create_options = 0x%x, "
1424 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1425 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1426 (unsigned int)share_access, (unsigned int)create_options,
1427 (unsigned int)create_disposition,
1428 (unsigned int)file_attributes));
1429
1430 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1431 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1432 is_ntfs_stream_smb_fname(smb_dname)) {
1433 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1434 smb_fname_str_dbg(smb_dname)));
1435 return NT_STATUS_NOT_A_DIRECTORY;
1436 }
1437
1438 switch (create_disposition) {
1439 case FILE_OPEN:
1440 /* If directory exists open. If directory doesn't
1441 * exist error. */
1442 create_flags = 0;
1443 info = FILE_WAS_OPENED;
1444 break;
1445 case FILE_CREATE:
1446 /* If directory exists error. If directory doesn't
1447 * exist create. */
1448 create_flags = O_CREAT | O_EXCL;
1449 info = FILE_WAS_CREATED;
1450 break;
1451 case FILE_OPEN_IF:
1452 /* If directory exists open. If directory doesn't
1453 * exist create. */
1454
1455 /* Note: in order to return whether the directory was
1456 * opened or created, we first try to open and then try
1457 * to create. */
1458 create_flags = 0;
1459 info = FILE_WAS_OPENED;
1460 break;
1461 case FILE_SUPERSEDE:
1462 case FILE_OVERWRITE:
1463 case FILE_OVERWRITE_IF:
1464 default:
1465 DEBUG(5, ("onefs_open_directory: invalid "
1466 "create_disposition 0x%x for directory %s\n",
1467 (unsigned int)create_disposition,
1468 smb_fname_str_dbg(smb_dname)));
1469 return NT_STATUS_INVALID_PARAMETER;
1470 }
1471
1472 /*
1473 * Check for write access to the share. Done in mkdir_internal() in
1474 * mainline samba.
1475 */
1476 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1477 return NT_STATUS_ACCESS_DENIED;
1478 }
1479
1480 /* Get parent dirname */
1481 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1482 NULL)) {
1483 return NT_STATUS_NO_MEMORY;
1484 }
1485
1486 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1487 posix_open = true;
1488 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1489 file_attributes = 0;
1490 } else {
1491 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
1492 }
1493
1494 /*
1495 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1496 * directories, no matter if you specify that they should be set.
1497 */
1498 file_attributes &=
1499 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1500
1501 status = file_new(req, conn, &fsp);
1502 if(!NT_STATUS_IS_OK(status)) {
1503 return status;
1504 }
1505
1506 /*
1507 * Actual open with retry magic to handle FILE_OPEN_IF which is
1508 * unique because the kernel won't tell us if the file was opened or
1509 * created.
1510 */
1511 retry_open:
1512 fsp->fh->fd = onefs_sys_create_file(conn,
1513 -1,
1514 smb_dname->base_name,
1515 access_mask,
1516 access_mask,
1517 share_access,
1518 create_options,
1519 create_flags | O_DIRECTORY,
1520 mode,
1521 0,
1522 0,
1523 sd,
1524 file_attributes,
1525 NULL);
1526
1527 if (fsp->fh->fd == -1) {
1528 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1529 smb_fname_str_dbg(smb_dname), errno,
1530 strerror(errno)));
1531 SMB_ASSERT(errno != EINPROGRESS);
1532
1533 if (create_disposition == FILE_OPEN_IF) {
1534 if (errno == ENOENT) {
1535 /* Try again, creating it this time. */
1536 create_flags = O_CREAT | O_EXCL;
1537 info = FILE_WAS_CREATED;
1538 goto retry_open;
1539 } else if (errno == EEXIST) {
1540 /* Uggh. Try again again. */
1541 create_flags = 0;
1542 info = FILE_WAS_OPENED;
1543 goto retry_open;
1544 }
1545 }
1546
1547 /* Error cases below: */
1548 file_free(req, fsp);
1549
1550 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1551 DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
1552 "for directory %s and it doesn't "
1553 "exist.\n", smb_fname_str_dbg(smb_dname)));
1554 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1555 } else if ((errno == EEXIST) &&
1556 (create_disposition == FILE_CREATE)) {
1557 DEBUG(5, ("onefs_open_directory: FILE_CREATE "
1558 "requested for directory %s and it "
1559 "already exists.\n",
1560 smb_fname_str_dbg(smb_dname)));
1561 return NT_STATUS_OBJECT_NAME_COLLISION;
1562 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1563 /* Catch sharing violations. */
1564 return NT_STATUS_SHARING_VIOLATION;
1565 }
1566
1567 return map_nt_error_from_unix(errno);
1568 }
1569
1570 if (info == FILE_WAS_CREATED) {
1571
1572 /* Pulled from mkdir_internal() */
1573 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1574 DEBUG(2, ("Could not stat directory '%s' just "
1575 "created: %s\n",
1576 smb_fname_str_dbg(smb_dname),
1577 strerror(errno)));
1578 return map_nt_error_from_unix(errno);
1579 }
1580
1581 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1582 DEBUG(0, ("Directory just '%s' created is not a "
1583 "directory\n",
1584 smb_fname_str_dbg(smb_dname)));
1585 return NT_STATUS_ACCESS_DENIED;
1586 }
1587
1588 if (!posix_open) {
1589 /*
1590 * Check if high bits should have been set, then (if
1591 * bits are missing): add them. Consider bits
1592 * automagically set by UNIX, i.e. SGID bit from
1593 * parent dir.
1594 */
1595 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1596 (mode & ~smb_dname->st.st_ex_mode)) {
1597 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1598 (smb_dname->st.st_ex_mode |
1599 (mode & ~smb_dname->st.st_ex_mode)));
1600 }
1601 }
1602
1603 /* Change the owner if required. */
1604 if (lp_inherit_owner(SNUM(conn))) {
1605 change_dir_owner_to_parent(conn, parent_dir,
1606 smb_dname->base_name,
1607 &smb_dname->st);
1608 }
1609
1610 notify_fname(conn, NOTIFY_ACTION_ADDED,
1611 FILE_NOTIFY_CHANGE_DIR_NAME,
1612 smb_dname->base_name);
1613 }
1614
1615 /* Stat the fd for Samba bookkeeping. */
1616 if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1617 fd_close(fsp);
1618 file_free(req, fsp);
1619 return map_nt_error_from_unix(errno);
1620 }
1621
1622 /* Setup the files_struct for it. */
1623 fsp->mode = smb_dname->st.st_ex_mode;
1624 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1625 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1626 fsp->file_pid = req ? req->smbpid : 0;
1627 fsp->can_lock = False;
1628 fsp->can_read = False;
1629 fsp->can_write = False;
1630
1631 fsp->share_access = share_access;
1632 fsp->fh->private_options = create_options;
1633 /*
1634 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1635 */
1636 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1637 fsp->print_file = False;
1638 fsp->modified = False;
1639 fsp->oplock_type = NO_OPLOCK;
1640 fsp->sent_oplock_break = NO_BREAK_SENT;
1641 fsp->is_directory = True;
1642 fsp->posix_open = posix_open;
1643
1644 status = fsp_set_smb_fname(fsp, smb_dname);
1645 if (!NT_STATUS_IS_OK(status)) {
1646 fd_close(fsp);
1647 file_free(req, fsp);
1648 return status;
1649 }
1650
1651 mtimespec = smb_dname->st.st_ex_mtime;
1652
1653 /*
1654 * Still set the samba share mode lock for correct delete-on-close
1655 * semantics and to make smbstatus more useful.
1656 */
1657 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1658 conn->connectpath, smb_dname, &mtimespec);
1659
1660 if (lck == NULL) {
1661 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1662 "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1663 fd_close(fsp);
1664 file_free(req, fsp);
1665 return NT_STATUS_SHARING_VIOLATION;
1666 }
1667
1668 if (lck->delete_on_close) {
1669 TALLOC_FREE(lck);
1670 fd_close(fsp);
1671 file_free(req, fsp);
1672 return NT_STATUS_DELETE_PENDING;
1673 }
1674
1675 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1676
1677 /*
1678 * For directories the delete on close bit at open time seems
1679 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1680 */
1681 if (create_options & FILE_DELETE_ON_CLOSE) {
1682 status = can_set_delete_on_close(fsp, 0);
1683 if (!NT_STATUS_IS_OK(status) &&
1684 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1685 TALLOC_FREE(lck);
1686 fd_close(fsp);
1687 file_free(req, fsp);
1688 return status;
1689 }
1690
1691 if (NT_STATUS_IS_OK(status)) {
1692 /* Note that here we set the *inital* delete on close flag,
1693 not the regular one. The magic gets handled in close. */
1694 fsp->initial_delete_on_close = True;
1695 }
1696 }
1697
1698 TALLOC_FREE(lck);
1699
1700 if (pinfo) {
1701 *pinfo = info;
1702 }
1703
1704 *result = fsp;
1705 return NT_STATUS_OK;
1706}
1707
1708/*
1709 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1710 */
1711static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1712 struct smb_request *req,
1713 struct smb_filename *smb_fname,
1714 uint32_t access_mask,
1715 uint32_t share_access,
1716 uint32_t create_disposition,
1717 uint32_t create_options,
1718 uint32_t file_attributes,
1719 uint32_t oplock_request,
1720 uint64_t allocation_size,
1721 struct security_descriptor *sd,
1722 struct ea_list *ea_list,
1723 files_struct **result,
1724 int *pinfo,
1725 struct onefs_fsp_data *fsp_data)
1726{
1727 int info = FILE_WAS_OPENED;
1728 files_struct *base_fsp = NULL;
1729 files_struct *fsp = NULL;
1730 NTSTATUS status;
1731
1732 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1733 "file_attributes = 0x%x, share_access = 0x%x, "
1734 "create_disposition = 0x%x create_options = 0x%x "
1735 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1736 "fname = %s\n",
1737 (unsigned int)access_mask,
1738 (unsigned int)file_attributes,
1739 (unsigned int)share_access,
1740 (unsigned int)create_disposition,
1741 (unsigned int)create_options,
1742 (unsigned int)oplock_request,
1743 ea_list, sd, smb_fname_str_dbg(smb_fname)));
1744
1745 if (create_options & FILE_OPEN_BY_FILE_ID) {
1746 status = NT_STATUS_NOT_SUPPORTED;
1747 goto fail;
1748 }
1749
1750 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1751 status = NT_STATUS_INVALID_PARAMETER;
1752 goto fail;
1753 }
1754
1755 if (req == NULL) {
1756 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1757 NO_OPLOCK);
1758 oplock_request |= INTERNAL_OPEN_ONLY;
1759 }
1760
1761 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1762 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1763 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1764 }
1765
1766 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1767 && (access_mask & DELETE_ACCESS)
1768 && !is_ntfs_stream_smb_fname(smb_fname)) {
1769 /*
1770 * We can't open a file with DELETE access if any of the
1771 * streams is open without FILE_SHARE_DELETE
1772 */
1773 status = open_streams_for_delete(conn, smb_fname->base_name);
1774
1775 if (!NT_STATUS_IS_OK(status)) {
1776 goto fail;
1777 }
1778 }
1779
1780 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1781 && is_ntfs_stream_smb_fname(smb_fname)) {
1782 uint32 base_create_disposition;
1783 struct smb_filename *smb_fname_base = NULL;
1784
1785 if (create_options & FILE_DIRECTORY_FILE) {
1786 status = NT_STATUS_NOT_A_DIRECTORY;
1787 goto fail;
1788 }
1789
1790 switch (create_disposition) {
1791 case FILE_OPEN:
1792 base_create_disposition = FILE_OPEN;
1793 break;
1794 default:
1795 base_create_disposition = FILE_OPEN_IF;
1796 break;
1797 }
1798
1799 /* Create an smb_filename with stream_name == NULL. */
1800 status = create_synthetic_smb_fname(talloc_tos(),
1801 smb_fname->base_name,
1802 NULL, NULL,
1803 &smb_fname_base);
1804 if (!NT_STATUS_IS_OK(status)) {
1805 goto fail;
1806 }
1807
1808 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1809 DEBUG(10, ("Unable to stat stream: %s\n",
1810 smb_fname_str_dbg(smb_fname_base)));
1811 }
1812
1813 status = onefs_create_file_unixpath(
1814 conn, /* conn */
1815 NULL, /* req */
1816 smb_fname_base, /* fname */
1817 SYNCHRONIZE_ACCESS, /* access_mask */
1818 (FILE_SHARE_READ |
1819 FILE_SHARE_WRITE |
1820 FILE_SHARE_DELETE), /* share_access */
1821 base_create_disposition, /* create_disposition*/
1822 0, /* create_options */
1823 file_attributes, /* file_attributes */
1824 NO_OPLOCK, /* oplock_request */
1825 0, /* allocation_size */
1826 NULL, /* sd */
1827 NULL, /* ea_list */
1828 &base_fsp, /* result */
1829 NULL, /* pinfo */
1830 NULL); /* fsp_data */
1831
1832 TALLOC_FREE(smb_fname_base);
1833
1834 if (!NT_STATUS_IS_OK(status)) {
1835 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1836 "failed: %s\n", smb_fname->base_name,
1837 nt_errstr(status)));
1838 goto fail;
1839 }
1840
1841 /*
1842 * Testing against windows xp/2003/vista shows that oplocks
1843 * can actually be requested and granted on streams (see the
1844 * RAW-OPLOCK-STREAM1 smbtorture test).
1845 */
1846 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1847 NO_OPLOCK) {
1848 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1849 "Ignoring oplock request: fname=%s\n",
1850 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1851 smb_fname_str_dbg(smb_fname)));
1852 /* Request NO_OPLOCK instead. */
1853 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1854 }
1855 }
1856
1857 /* Covert generic bits in the security descriptor. */
1858 if (sd != NULL) {
1859 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1860 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1861 }
1862
1863 /*
1864 * If it's a request for a directory open, deal with it separately.
1865 */
1866
1867 if (create_options & FILE_DIRECTORY_FILE) {
1868
1869 if (create_options & FILE_NON_DIRECTORY_FILE) {
1870 status = NT_STATUS_INVALID_PARAMETER;
1871 goto fail;
1872 }
1873
1874 /* Can't open a temp directory. IFS kit test. */
1875 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1876 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1877 status = NT_STATUS_INVALID_PARAMETER;
1878 goto fail;
1879 }
1880
1881 /*
1882 * We will get a create directory here if the Win32
1883 * app specified a security descriptor in the
1884 * CreateDirectory() call.
1885 */
1886
1887 status = onefs_open_directory(
1888 conn, /* conn */
1889 req, /* req */
1890 smb_fname, /* fname */
1891 access_mask, /* access_mask */
1892 share_access, /* share_access */
1893 create_disposition, /* create_disposition*/
1894 create_options, /* create_options */
1895 file_attributes, /* file_attributes */
1896 sd, /* sd */
1897 &fsp, /* result */
1898 &info); /* pinfo */
1899 } else {
1900
1901 /*
1902 * Ordinary file case.
1903 */
1904
1905 status = file_new(req, conn, &fsp);
1906 if(!NT_STATUS_IS_OK(status)) {
1907 goto fail;
1908 }
1909
1910 /*
1911 * We're opening the stream element of a base_fsp
1912 * we already opened. Set up the base_fsp pointer.
1913 */
1914 if (base_fsp) {
1915 fsp->base_fsp = base_fsp;
1916 }
1917
1918 status = onefs_open_file_ntcreate(
1919 conn, /* conn */
1920 req, /* req */
1921 smb_fname, /* fname */
1922 access_mask, /* access_mask */
1923 share_access, /* share_access */
1924 create_disposition, /* create_disposition*/
1925 create_options, /* create_options */
1926 file_attributes, /* file_attributes */
1927 oplock_request, /* oplock_request */
1928 sd, /* sd */
1929 fsp, /* result */
1930 &info, /* pinfo */
1931 fsp_data); /* fsp_data */
1932
1933 if(!NT_STATUS_IS_OK(status)) {
1934 file_free(req, fsp);
1935 fsp = NULL;
1936 }
1937
1938 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1939
1940 /* A stream open never opens a directory */
1941
1942 if (base_fsp) {
1943 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1944 goto fail;
1945 }
1946
1947 /*
1948 * Fail the open if it was explicitly a non-directory
1949 * file.
1950 */
1951
1952 if (create_options & FILE_NON_DIRECTORY_FILE) {
1953 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1954 goto fail;
1955 }
1956
1957 create_options |= FILE_DIRECTORY_FILE;
1958
1959 status = onefs_open_directory(
1960 conn, /* conn */
1961 req, /* req */
1962 smb_fname, /* fname */
1963 access_mask, /* access_mask */
1964 share_access, /* share_access */
1965 create_disposition, /* create_disposition*/
1966 create_options, /* create_options */
1967 file_attributes, /* file_attributes */
1968 sd, /* sd */
1969 &fsp, /* result */
1970 &info); /* pinfo */
1971 }
1972 }
1973
1974 if (!NT_STATUS_IS_OK(status)) {
1975 goto fail;
1976 }
1977
1978 fsp->base_fsp = base_fsp;
1979
1980 SMB_ASSERT(fsp);
1981
1982 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1983 status = set_ea(conn, fsp, smb_fname, ea_list);
1984 if (!NT_STATUS_IS_OK(status)) {
1985 goto fail;
1986 }
1987 }
1988
1989 if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1990 status = NT_STATUS_ACCESS_DENIED;
1991 goto fail;
1992 }
1993
1994 /* Save the requested allocation size. */
1995 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1996 if (allocation_size
1997 && (allocation_size > smb_fname->st.st_ex_size)) {
1998 fsp->initial_allocation_size = smb_roundup(
1999 fsp->conn, allocation_size);
2000 if (fsp->is_directory) {
2001 /* Can't set allocation size on a directory. */
2002 status = NT_STATUS_ACCESS_DENIED;
2003 goto fail;
2004 }
2005 if (vfs_allocate_file_space(
2006 fsp, fsp->initial_allocation_size) == -1) {
2007 status = NT_STATUS_DISK_FULL;
2008 goto fail;
2009 }
2010 } else {
2011 fsp->initial_allocation_size = smb_roundup(
2012 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
2013 }
2014 }
2015
2016 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
2017
2018 *result = fsp;
2019 if (pinfo != NULL) {
2020 *pinfo = info;
2021 }
2022 if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
2023 SMB_VFS_FSTAT(fsp, &smb_fname->st);
2024 }
2025 return NT_STATUS_OK;
2026
2027 fail:
2028 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
2029
2030 if (fsp != NULL) {
2031 if (base_fsp && fsp->base_fsp == base_fsp) {
2032 /*
2033 * The close_file below will close
2034 * fsp->base_fsp.
2035 */
2036 base_fsp = NULL;
2037 }
2038 close_file(req, fsp, ERROR_CLOSE);
2039 fsp = NULL;
2040 }
2041 if (base_fsp != NULL) {
2042 close_file(req, base_fsp, ERROR_CLOSE);
2043 base_fsp = NULL;
2044 }
2045 return status;
2046}
2047
2048static void destroy_onefs_fsp_data(void *p_data)
2049{
2050 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
2051
2052 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2053}
2054
2055/**
2056 * SMB_VFS_CREATE_FILE interface to onefs.
2057 */
2058NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2059 struct smb_request *req,
2060 uint16_t root_dir_fid,
2061 struct smb_filename *smb_fname,
2062 uint32_t access_mask,
2063 uint32_t share_access,
2064 uint32_t create_disposition,
2065 uint32_t create_options,
2066 uint32_t file_attributes,
2067 uint32_t oplock_request,
2068 uint64_t allocation_size,
2069 struct security_descriptor *sd,
2070 struct ea_list *ea_list,
2071 files_struct **result,
2072 int *pinfo)
2073{
2074 connection_struct *conn = handle->conn;
2075 struct onefs_fsp_data fsp_data = {};
2076 int info = FILE_WAS_OPENED;
2077 files_struct *fsp = NULL;
2078 NTSTATUS status;
2079
2080 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2081 "file_attributes = 0x%x, share_access = 0x%x, "
2082 "create_disposition = 0x%x create_options = 0x%x "
2083 "oplock_request = 0x%x "
2084 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2085 "fname = %s\n",
2086 (unsigned int)access_mask,
2087 (unsigned int)file_attributes,
2088 (unsigned int)share_access,
2089 (unsigned int)create_disposition,
2090 (unsigned int)create_options,
2091 (unsigned int)oplock_request,
2092 (unsigned int)root_dir_fid,
2093 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2094
2095 /* Get the file name if root_dir_fid was specified. */
2096 if (root_dir_fid != 0) {
2097 status = get_relative_fid_filename(conn, req, root_dir_fid,
2098 smb_fname);
2099 if (!NT_STATUS_IS_OK(status)) {
2100 goto fail;
2101 }
2102 }
2103
2104 /* All file access must go through check_name() */
2105 status = check_name(conn, smb_fname->base_name);
2106 if (!NT_STATUS_IS_OK(status)) {
2107 goto fail;
2108 }
2109
2110 status = onefs_create_file_unixpath(
2111 conn, /* conn */
2112 req, /* req */
2113 smb_fname, /* fname */
2114 access_mask, /* access_mask */
2115 share_access, /* share_access */
2116 create_disposition, /* create_disposition*/
2117 create_options, /* create_options */
2118 file_attributes, /* file_attributes */
2119 oplock_request, /* oplock_request */
2120 allocation_size, /* allocation_size */
2121 sd, /* sd */
2122 ea_list, /* ea_list */
2123 &fsp, /* result */
2124 &info, /* pinfo */
2125 &fsp_data); /* psbuf */
2126
2127 if (!NT_STATUS_IS_OK(status)) {
2128 goto fail;
2129 }
2130
2131 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2132
2133 /*
2134 * Setup private onefs_fsp_data. Currently the private data struct is
2135 * only used to store the oplock_callback_id so that when the file is
2136 * closed, the onefs_callback_record can be properly cleaned up in the
2137 * oplock_onefs sub-system.
2138 */
2139 if (fsp) {
2140 struct onefs_fsp_data *fsp_data_tmp = NULL;
2141 fsp_data_tmp = (struct onefs_fsp_data *)
2142 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2143 &destroy_onefs_fsp_data);
2144
2145 if (fsp_data_tmp == NULL) {
2146 status = NT_STATUS_NO_MEMORY;
2147 goto fail;
2148 }
2149
2150 *fsp_data_tmp = fsp_data;
2151 }
2152
2153 *result = fsp;
2154 if (pinfo != NULL) {
2155 *pinfo = info;
2156 }
2157 return NT_STATUS_OK;
2158
2159 fail:
2160 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2161
2162 if (fsp != NULL) {
2163 close_file(req, fsp, ERROR_CLOSE);
2164 fsp = NULL;
2165 }
2166 return status;
2167}
Note: See TracBrowser for help on using the repository browser.