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

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

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