2
* Unix SMB/CIFS implementation.
4
* This file began with some code from source3/smbd/open.c and has been
5
* modified it work with ifs_createfile.
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
13
* - Setting security descriptors at create time
14
* - Setting dos_attributes at create time
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
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.
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.
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/>.
37
#include "onefs_config.h"
38
#include "oplock_onefs.h"
39
#include "smbd/globals.h"
41
extern const struct generic_mapping file_generic_mapping;
43
struct onefs_fsp_data {
44
uint64_t oplock_callback_id;
47
static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
48
struct smb_request *req,
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,
61
struct onefs_fsp_data *fsp_data,
62
SMB_STRUCT_STAT *psbuf);
64
/****************************************************************************
66
****************************************************************************/
68
static NTSTATUS onefs_open_file(files_struct *fsp,
69
connection_struct *conn,
70
struct smb_request *req,
71
const char *parent_dir,
74
SMB_STRUCT_STAT *psbuf,
78
uint32 open_access_mask,
82
uint32 create_options,
83
uint32_t new_dos_attributes,
84
struct security_descriptor *sd,
87
NTSTATUS status = NT_STATUS_OK;
88
int accmode = (flags & O_ACCMODE);
89
int local_flags = flags;
90
bool file_existed = VALID_STAT(*psbuf);
99
/* Check permissions */
102
* This code was changed after seeing a client open request
103
* containing the open mode of (DENY_WRITE/read-only) with
104
* the 'create if not exist' bit set. The previous code
105
* would fail to open the file read only on a read-only share
106
* as it was checking the flags parameter directly against O_RDONLY,
107
* this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
111
if (!CAN_WRITE(conn)) {
112
/* It's a read-only share - fail if we wanted to write. */
113
if(accmode != O_RDONLY) {
114
DEBUG(3,("Permission denied opening %s\n", path));
115
return NT_STATUS_ACCESS_DENIED;
116
} else if(flags & O_CREAT) {
117
/* We don't want to write - but we must make sure that
118
O_CREAT doesn't create the file if we have write
119
access into the directory.
122
local_flags &= ~O_CREAT;
127
* This little piece of insanity is inspired by the
128
* fact that an NT client can open a file for O_RDONLY,
129
* but set the create disposition to FILE_EXISTS_TRUNCATE.
130
* If the client *can* write to the file, then it expects to
131
* truncate the file, even though it is opening for readonly.
132
* Quicken uses this stupid trick in backup file creation...
133
* Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
134
* for helping track this one down. It didn't bite us in 2.0.x
135
* as we always opened files read-write in that release. JRA.
138
if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
139
DEBUG(10,("onefs_open_file: truncate requested on read-only "
140
"open for file %s\n", path));
141
local_flags = (flags & ~O_ACCMODE)|O_RDWR;
144
#if defined(O_NONBLOCK) && defined(S_ISFIFO)
146
* We would block on opening a FIFO with no one else on the
147
* other end. Do what we used to do and add O_NONBLOCK to the
151
if (file_existed && S_ISFIFO(psbuf->st_mode)) {
152
local_flags |= O_NONBLOCK;
156
/* Don't create files with Microsoft wildcard characters. */
159
* wildcard characters are allowed in stream names
160
* only test the basefilename
162
wild = fsp->base_fsp->fsp_name;
166
if ((local_flags & O_CREAT) && !file_existed &&
169
* XXX: may need to remvoe this return...
171
* We dont think this check needs to exist. All it does is
172
* block creating files with Microsoft wildcards, which is
173
* fine if the creation originated from NFS or locally and
174
* then was copied via Samba.
176
DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
178
return NT_STATUS_OBJECT_NAME_INVALID;
181
/* Actually do the open */
185
* Never follow symlinks on a POSIX client. The
186
* client should be doing this.
189
if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
193
/* Stream handling */
194
if (is_ntfs_stream_name(path)) {
195
status = onefs_split_ntfs_stream_name(talloc_tos(), path,
198
/* It's a stream, so pass in the base_fd */
199
if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
200
SMB_ASSERT(fsp->base_fsp);
202
DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n",
203
base, fsp->base_fsp->fh->fd, stream));
205
base_fd = fsp->base_fsp->fh->fd;
208
fsp->fh->fd = onefs_sys_create_file(conn,
210
stream != NULL ? stream :
211
(base != NULL ? base : path),
224
if (fsp->fh->fd == -1) {
225
if (errno == EMFILE) {
226
static time_t last_warned = 0L;
228
if (time((time_t *) NULL) > last_warned) {
229
DEBUG(0, ("Too many open files, unable "
230
"to open more! smbd's max "
231
"open files = %d, also check "
232
"sysctl kern.maxfiles and "
233
"sysctl kern.maxfilesperproc\n",
234
lp_max_open_files()));
235
last_warned = time((time_t *) NULL);
239
status = map_nt_error_from_unix(errno);
240
DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
242
path, strerror(errno), local_flags, flags));
246
if ((local_flags & O_CREAT) && !file_existed) {
248
/* Inherit the ACL if required */
249
if (lp_inherit_perms(SNUM(conn))) {
250
inherit_access_posix_acl(conn, parent_dir, path,
254
/* Change the owner if required. */
255
if (lp_inherit_owner(SNUM(conn))) {
256
change_file_owner_to_parent(conn, parent_dir,
260
notify_fname(conn, NOTIFY_ACTION_ADDED,
261
FILE_NOTIFY_CHANGE_FILE_NAME, path);
267
if (fsp->fh->fd == -1) {
268
ret = SMB_VFS_STAT(conn, path, psbuf);
270
ret = SMB_VFS_FSTAT(fsp, psbuf);
271
/* If we have an fd, this stat should succeed. */
273
DEBUG(0,("Error doing fstat on open file %s "
274
"(%s)\n", path,strerror(errno) ));
278
/* For a non-io open, this stat failing means file not found. JRA */
280
status = map_nt_error_from_unix(errno);
287
* POSIX allows read-only opens of directories. We don't
288
* want to do this (we use a different code path for this)
289
* so catch a directory open and return an EISDIR. JRA.
292
if(S_ISDIR(psbuf->st_mode)) {
295
return NT_STATUS_FILE_IS_A_DIRECTORY;
298
fsp->mode = psbuf->st_mode;
299
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
300
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
301
fsp->file_pid = req ? req->smbpid : 0;
302
fsp->can_lock = True;
303
fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
304
if (!CAN_WRITE(conn)) {
305
fsp->can_write = False;
307
fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
310
fsp->print_file = False;
311
fsp->modified = False;
312
fsp->sent_oplock_break = NO_BREAK_SENT;
313
fsp->is_directory = False;
314
if (conn->aio_write_behind_list &&
315
is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
316
fsp->aio_write_behind = True;
319
string_set(&fsp->fsp_name, path);
320
fsp->wcp = NULL; /* Write cache pointer. */
322
DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
323
conn->server_info->unix_name,
325
BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
326
conn->num_files_open));
332
/****************************************************************************
333
Handle the 1 second delay in returning a SHARING_VIOLATION error.
334
****************************************************************************/
336
static void defer_open(struct share_mode_lock *lck,
337
struct timeval request_time,
338
struct timeval timeout,
339
struct smb_request *req,
340
struct deferred_open_record *state)
346
for (i=0; i<lck->num_share_modes; i++) {
347
struct share_mode_entry *e = &lck->share_modes[i];
349
if (!is_deferred_open_entry(e)) {
353
if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
354
DEBUG(0, ("Trying to defer an already deferred "
355
"request: mid=%d, exiting\n", req->mid));
356
exit_server("attempt to defer a deferred request");
360
/* End paranoia check */
362
DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
363
"open entry for mid %u\n",
364
(unsigned int)request_time.tv_sec,
365
(unsigned int)request_time.tv_usec,
366
(unsigned int)req->mid));
368
if (!push_deferred_smb_message(req, request_time, timeout,
369
(char *)state, sizeof(*state))) {
370
exit_server("push_deferred_smb_message failed");
372
add_deferred_open(lck, req->mid, request_time, state->id);
375
* Push the MID of this packet on the signing queue.
376
* We only do this once, the first time we push the packet
377
* onto the deferred open queue, as this has a side effect
378
* of incrementing the response sequence number.
381
srv_defer_sign_response(req->mid);
384
static void schedule_defer_open(struct share_mode_lock *lck,
385
struct timeval request_time,
386
struct smb_request *req)
388
struct deferred_open_record state;
390
/* This is a relative time, added to the absolute
391
request_time value to get the absolute timeout time.
392
Note that if this is the second or greater time we enter
393
this codepath for this particular request mid then
394
request_time is left as the absolute time of the *first*
395
time this request mid was processed. This is what allows
396
the request to eventually time out. */
398
struct timeval timeout;
400
/* Normally the smbd we asked should respond within
401
* OPLOCK_BREAK_TIMEOUT seconds regardless of whether
402
* the client did, give twice the timeout as a safety
403
* measure here in case the other smbd is stuck
407
* On OneFS, the kernel will always send an oplock_revoked message
408
* before this timeout is hit.
410
timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
412
/* Nothing actually uses state.delayed_for_oplocks
413
but it's handy to differentiate in debug messages
414
between a 30 second delay due to oplock break, and
415
a 1 second delay for share mode conflicts. */
417
state.delayed_for_oplocks = True;
418
state.failed = false;
421
if (!request_timed_out(request_time, timeout)) {
422
defer_open(lck, request_time, timeout, req, &state);
426
/****************************************************************************
427
Open a file with a share mode. Passed in an already created files_struct.
428
****************************************************************************/
429
NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
430
struct smb_request *req,
434
uint32 create_disposition,
435
uint32 create_options,
436
uint32 new_dos_attributes,
438
struct security_descriptor *sd,
441
struct onefs_fsp_data *fsp_data,
442
SMB_STRUCT_STAT *psbuf)
446
bool file_existed = VALID_STAT(*psbuf);
447
bool def_acl = False;
448
bool posix_open = False;
449
bool new_file_created = False;
450
bool clear_ads = False;
452
mode_t new_unx_mode = (mode_t)0;
453
mode_t unx_mode = (mode_t)0;
455
uint32 existing_dos_attributes = 0;
456
struct pending_message_list *pml = NULL;
457
struct timeval request_time = timeval_zero();
458
struct share_mode_lock *lck = NULL;
459
uint32 open_access_mask = access_mask;
465
uint64_t oplock_callback_id = 0;
466
uint32 createfile_attributes = 0;
472
* Printers are handled completely differently.
473
* Most of the passed parameters are ignored.
477
*pinfo = FILE_WAS_CREATED;
480
DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
483
return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
486
if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
487
return NT_STATUS_NO_MEMORY;
490
if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
492
unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
493
new_dos_attributes = 0;
495
/* We add aARCH to this as this mode is only used if the file is
497
unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
501
DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
502
"access_mask=0x%x share_access=0x%x "
503
"create_disposition = 0x%x create_options=0x%x "
504
"unix mode=0%o oplock_request=0x%x\n",
505
fname, new_dos_attributes, access_mask, share_access,
506
create_disposition, create_options, unx_mode,
510
* Any non-stat-only open has the potential to contend oplocks, which
511
* means to avoid blocking in the kernel (which is unacceptable), the
512
* open must be deferred. In order to defer opens, req must not be
513
* NULL. The known cases of calling with a NULL req:
515
* 1. Open the base file of a stream: Always done stat-only
517
* 2. open_file_fchmod(), which is called from 3 places:
518
* A. try_chown: Posix acls only. Never called on onefs.
519
* B. set_ea_dos_attributes: Can't be called from onefs, because
520
* SMB_VFS_SETXATTR return ENOSYS.
521
* C. file_set_dos_mode: This would only happen if the "dos
522
* filemode" smb.conf parameter is set to yes. We ship with
523
* it off, but if a customer were to turn it on it would be
526
if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
527
smb_panic("NULL req on a non-stat-open!");
530
if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
531
DEBUG(0, ("No smb request but not an internal only open!\n"));
532
return NT_STATUS_INTERNAL_ERROR;
536
* Only non-internal opens can be deferred at all
540
&& ((pml = get_open_deferred_message(req->mid)) != NULL)) {
541
struct deferred_open_record *state =
542
(struct deferred_open_record *)pml->private_data.data;
544
/* Remember the absolute time of the original
545
request with this mid. We'll use it later to
546
see if this has timed out. */
548
request_time = pml->request_time;
550
/* Remove the deferred open entry under lock. */
551
lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
554
DEBUG(0, ("could not get share mode lock\n"));
556
del_deferred_open_entry(lck, req->mid);
560
/* Ensure we don't reprocess this message. */
561
remove_deferred_open_smb_message(req->mid);
564
* When receiving a semlock_async_failure message, the
565
* deferred open will be marked as "failed". Returning
569
DEBUG(0, ("onefs_open_file_ntcreate: "
570
"semlock_async_failure detected!\n"));
571
return NT_STATUS_INTERNAL_ERROR;
575
status = check_name(conn, fname);
576
if (!NT_STATUS_IS_OK(status)) {
581
new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
583
existing_dos_attributes = dos_mode(conn, fname, psbuf);
587
/* Setup dos_attributes to be set by ifs_createfile */
588
if (lp_store_dos_attributes(SNUM(conn))) {
589
createfile_attributes = (new_dos_attributes | aARCH) &
590
~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
593
/* Ignore oplock requests if oplocks are disabled. */
594
if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
595
IS_VETO_OPLOCK_PATH(conn, fname)) {
596
/* Mask off everything except the private Samba bits. */
597
oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
600
/* this is for OS/2 long file names - say we don't support them */
601
if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
602
/* OS/2 Workplace shell fix may be main code stream in a later
604
DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
605
"not supported.\n"));
606
if (use_nt_status()) {
607
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
609
return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
612
switch( create_disposition ) {
614
* Currently we're using FILE_SUPERSEDE as the same as
615
* FILE_OVERWRITE_IF but they really are
616
* different. FILE_SUPERSEDE deletes an existing file
617
* (requiring delete access) then recreates it.
621
* @todo: Clear all file attributes?
622
* http://www.osronline.com/article.cfm?article=302
623
* create if not exist, trunc if exist
625
* If file exists replace/overwrite. If file doesn't
628
flags2 |= (O_CREAT | O_TRUNC);
632
case FILE_OVERWRITE_IF:
633
/* If file exists replace/overwrite. If file doesn't
635
flags2 |= (O_CREAT | O_TRUNC);
640
/* If file exists open. If file doesn't exist error. */
642
DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
643
"requested for file %s and file "
644
"doesn't exist.\n", fname ));
646
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
651
/* If file exists overwrite. If file doesn't exist
654
DEBUG(5, ("onefs_open_file_ntcreate: "
655
"FILE_OVERWRITE requested for file "
656
"%s and file doesn't exist.\n",
659
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
666
/* If file exists error. If file doesn't exist
669
DEBUG(5, ("onefs_open_file_ntcreate: "
670
"FILE_CREATE requested for file %s "
671
"and file already exists.\n",
673
if (S_ISDIR(psbuf->st_mode)) {
678
return map_nt_error_from_unix(errno);
680
flags2 |= (O_CREAT|O_EXCL);
684
/* If file exists open. If file doesn't exist
690
return NT_STATUS_INVALID_PARAMETER;
693
/* Match attributes on file exists and overwrite. */
694
if (!posix_open && file_existed &&
695
((create_disposition == FILE_OVERWRITE) ||
696
(create_disposition == FILE_OVERWRITE_IF))) {
697
if (!open_match_attributes(conn, fname,
698
existing_dos_attributes,
699
new_dos_attributes, psbuf->st_mode,
700
unx_mode, &new_unx_mode)) {
701
DEBUG(5, ("onefs_open_file_ntcreate: attributes "
702
"missmatch for file %s (%x %x) (0%o, 0%o)\n",
703
fname, existing_dos_attributes,
705
(unsigned int)psbuf->st_mode,
706
(unsigned int)unx_mode ));
708
return NT_STATUS_ACCESS_DENIED;
713
* OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
714
* access_mask, but leave the MAA for the actual open in
717
open_access_mask = access_mask;
718
if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
719
access_mask |= FILE_GENERIC_ALL;
722
/* Convert GENERIC bits to specific bits. */
723
se_map_generic(&access_mask, &file_generic_mapping);
724
se_map_generic(&open_access_mask, &file_generic_mapping);
726
if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
727
/* This will cause oplock breaks. */
728
open_access_mask |= FILE_WRITE_DATA;
731
DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
732
"open_access_mask=%#x, access_mask=0x%x\n",
733
fname, open_access_mask, access_mask));
736
* Note that we ignore the append flag as append does not
737
* mean the same thing under DOS and Unix.
740
if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
741
(oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
744
* DENY_DOS opens are always underlying read-write on the
745
* file handle, no matter what the requested access mask
746
* says. Stock samba just sets the flags, but since
747
* ifs_createfile uses the access_mask, it must be updated as
748
* well. This allows BASE-DENY* to pass.
750
if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
752
DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
753
"Adding O_RDWR to flags "
754
"(0x%x) and some READ bits to "
755
"open_access_mask (0x%x)\n",
756
flags, open_access_mask));
759
open_access_mask |= (FILE_READ_ATTRIBUTES |
760
FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
762
} else if (access_mask & (FILE_READ_ATTRIBUTES |
774
/* Currently we only look at FILE_WRITE_THROUGH for create options. */
776
if ((create_options & FILE_WRITE_THROUGH) &&
777
lp_strict_sync(SNUM(conn))) {
782
if (posix_open && (access_mask & FILE_APPEND_DATA)) {
786
if (!posix_open && !CAN_WRITE(conn)) {
788
* We should really return a permission denied error if either
789
* O_CREAT or O_TRUNC are set, but for compatibility with
790
* older versions of Samba we just AND them out.
792
flags2 &= ~(O_CREAT|O_TRUNC);
794
/* Deny DELETE_ACCESS explicitly if the share is read only. */
795
if (access_mask & DELETE_ACCESS) {
796
return map_nt_error_from_unix(EACCES);
800
/* Ensure we can't write on a read-only share or file. */
801
if (flags != O_RDONLY && file_existed &&
802
(!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
803
DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
804
"for file %s on read only %s\n",
805
fname, !CAN_WRITE(conn) ? "share" : "file" ));
807
return NT_STATUS_ACCESS_DENIED;
810
DEBUG(10, ("fsp = %p\n", fsp));
812
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
813
fsp->share_access = share_access;
814
fsp->fh->private_options = create_options;
815
fsp->access_mask = open_access_mask; /* We change this to the
816
* requested access_mask after
817
* the open is done. */
818
fsp->posix_open = posix_open;
820
/* Ensure no SAMBA_PRIVATE bits can be set. */
821
fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
823
if (timeval_is_zero(&request_time)) {
824
request_time = fsp->open_time;
828
struct timespec old_write_time = get_mtimespec(psbuf);
829
id = vfs_file_id_from_sbuf(conn, psbuf);
831
lck = get_share_mode_lock(talloc_tos(), id,
833
fname, &old_write_time);
836
DEBUG(0, ("Could not get share mode lock\n"));
837
return NT_STATUS_SHARING_VIOLATION;
840
if (lck->delete_on_close) {
841
/* DELETE_PENDING is not deferred for a second */
843
return NT_STATUS_DELETE_PENDING;
847
SMB_ASSERT(!file_existed || (lck != NULL));
850
* Ensure we pay attention to default ACLs on directories. May be
851
* neccessary depending on ACL policies.
853
if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
854
(def_acl = directory_has_default_acl(conn, parent_dir))) {
858
DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
859
"mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
860
(unsigned int)flags, (unsigned int)flags2,
861
(unsigned int)unx_mode, (unsigned int)access_mask,
862
(unsigned int)open_access_mask));
865
* Since the open is guaranteed to be stat only if req == NULL, a
866
* callback record is only needed if req != NULL.
869
SMB_ASSERT(fsp_data);
870
oplock_callback_id = onefs_oplock_wait_record(req->mid);
871
if (oplock_callback_id == 0) {
872
return NT_STATUS_NO_MEMORY;
876
* It is also already asserted it's either a stream or a
877
* stat-only open at this point.
879
SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
883
status = onefs_open_file(fsp,
898
createfile_attributes,
902
if (!NT_STATUS_IS_OK(status)) {
904
/* OneFS Oplock Handling */
905
if (errno == EINPROGRESS) {
909
struct deferred_open_record state;
910
struct timespec old_write_time;
912
old_write_time = get_mtimespec(psbuf);
914
DEBUG(3, ("Someone created file %s with an "
915
"oplock after we looked: Retrying\n",
918
* We hit the race that when we did the stat
919
* on the file it did not exist, and someone
920
* has created it in between the stat and the
921
* open_file() call. Just retry immediately.
923
id = vfs_file_id_from_sbuf(conn, psbuf);
924
if (!(lck = get_share_mode_lock(talloc_tos(),
925
id, conn->connectpath, fname,
930
DEBUG(0, ("onefs_open_file_ntcreate: "
931
"Could not get share mode "
932
"lock for %s\n", fname));
933
status = NT_STATUS_SHARING_VIOLATION;
934
goto cleanup_destroy;
937
state.delayed_for_oplocks = False;
941
defer_open(lck, request_time,
942
timeval_zero(), req, &state);
944
goto cleanup_destroy;
946
/* Waiting for an oplock */
947
DEBUG(5,("Async createfile because a client has an "
948
"oplock on %s\n", fname));
951
schedule_defer_open(lck, request_time, req);
955
/* Check for a sharing violation */
956
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
957
uint32 can_access_mask;
958
bool can_access = True;
960
/* Check if this can be done with the deny_dos and fcb
963
/* Try to find dup fsp if possible. */
965
(NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
966
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
969
DEBUG(0, ("DOS open without an SMB "
971
status = NT_STATUS_INTERNAL_ERROR;
972
goto cleanup_destroy;
975
/* Use the client requested access mask here,
976
* not the one we open with. */
977
status = fcb_or_dos_open(req,
988
if (NT_STATUS_IS_OK(status)) {
990
*pinfo = FILE_WAS_OPENED;
992
status = NT_STATUS_OK;
998
* This next line is a subtlety we need for
999
* MS-Access. If a file open will fail due to share
1000
* permissions and also for security (access) reasons,
1001
* we need to return the access failed error, not the
1002
* share error. We can't open the file due to kernel
1003
* oplock deadlock (it's possible we failed above on
1004
* the open_mode_check()) so use a userspace check.
1007
if (flags & O_RDWR) {
1008
can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1009
} else if (flags & O_WRONLY) {
1010
can_access_mask = FILE_WRITE_DATA;
1012
can_access_mask = FILE_READ_DATA;
1015
if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
1016
!can_access_file_data(conn,fname,psbuf,can_access_mask)) {
1021
* If we're returning a share violation, ensure we
1022
* cope with the braindead 1 second delay.
1024
if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1025
lp_defer_sharing_violations()) {
1026
struct timeval timeout;
1027
struct deferred_open_record state;
1030
/* this is a hack to speed up torture tests
1032
timeout_usecs = lp_parm_int(SNUM(conn),
1033
"smbd","sharedelay",
1034
SHARING_VIOLATION_USEC_WAIT);
1036
/* This is a relative time, added to the
1037
absolute request_time value to get the
1038
absolute timeout time. Note that if this
1039
is the second or greater time we enter this
1040
codepath for this particular request mid
1041
then request_time is left as the absolute
1042
time of the *first* time this request mid
1043
was processed. This is what allows the
1044
request to eventually time out. */
1046
timeout = timeval_set(0, timeout_usecs);
1048
/* Nothing actually uses
1049
state.delayed_for_oplocks but it's handy to
1050
differentiate in debug messages between a
1051
30 second delay due to oplock break, and a
1052
1 second delay for share mode conflicts. */
1054
state.delayed_for_oplocks = False;
1056
state.failed = false;
1059
&& !request_timed_out(request_time,
1061
defer_open(lck, request_time, timeout,
1068
* We have detected a sharing violation here
1069
* so return the correct error code
1071
status = NT_STATUS_SHARING_VIOLATION;
1073
status = NT_STATUS_ACCESS_DENIED;
1076
goto cleanup_destroy;
1080
* Normal error, for example EACCES
1083
if (oplock_callback_id != 0) {
1084
destroy_onefs_callback_record(oplock_callback_id);
1091
fsp->oplock_type = granted_oplock;
1093
if (oplock_callback_id != 0) {
1094
onefs_set_oplock_callback(oplock_callback_id, fsp);
1095
fsp_data->oplock_callback_id = oplock_callback_id;
1097
SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1100
if (!file_existed) {
1101
struct timespec old_write_time = get_mtimespec(psbuf);
1103
* Deal with the race condition where two smbd's detect the
1104
* file doesn't exist and do the create at the same time. One
1105
* of them will win and set a share mode, the other (ie. this
1106
* one) should check if the requested share mode for this
1107
* create is allowed.
1111
* Now the file exists and fsp is successfully opened,
1112
* fsp->dev and fsp->inode are valid and should replace the
1113
* dev=0,inode=0 from a non existent file. Spotted by
1114
* Nadav Danieli <nadavd@exanet.com>. JRA.
1119
lck = get_share_mode_lock(talloc_tos(), id,
1121
fname, &old_write_time);
1124
DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1125
"share mode lock for %s\n", fname));
1127
return NT_STATUS_SHARING_VIOLATION;
1130
if (lck->delete_on_close) {
1131
status = NT_STATUS_DELETE_PENDING;
1134
if (!NT_STATUS_IS_OK(status)) {
1135
struct deferred_open_record state;
1139
state.delayed_for_oplocks = False;
1142
/* Do it all over again immediately. In the second
1143
* round we will find that the file existed and handle
1144
* the DELETE_PENDING and FCB cases correctly. No need
1145
* to duplicate the code here. Essentially this is a
1146
* "goto top of this function", but don't tell
1150
defer_open(lck, request_time, timeval_zero(),
1158
* We exit this block with the share entry *locked*.....
1163
SMB_ASSERT(lck != NULL);
1165
/* Delete streams if create_disposition requires it */
1166
if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) {
1167
status = delete_all_streams(conn, fname);
1168
if (!NT_STATUS_IS_OK(status)) {
1175
/* note that we ignore failure for the following. It is
1176
basically a hack for NFS, and NFS will never set one of
1177
these only read them. Nobody but Samba can ever set a deny
1178
mode and we have already checked our more authoritative
1179
locking database for permission to set this deny mode. If
1180
the kernel refuses the operations then the kernel is wrong.
1181
note that GPFS supports it as well - jmcd */
1183
if (fsp->fh->fd != -1) {
1184
ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1185
if(ret_flock == -1 ){
1189
return NT_STATUS_SHARING_VIOLATION;
1194
* At this point onwards, we can guarentee that the share entry
1195
* is locked, whether we created the file or not, and that the
1196
* deny mode is compatible with all current opens.
1199
/* Record the options we were opened with. */
1200
fsp->share_access = share_access;
1201
fsp->fh->private_options = create_options;
1203
* According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1205
fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1208
/* stat opens on existing files don't get oplocks. */
1209
if (is_stat_open(open_access_mask)) {
1210
fsp->oplock_type = NO_OPLOCK;
1213
if (!(flags2 & O_TRUNC)) {
1214
info = FILE_WAS_OPENED;
1216
info = FILE_WAS_OVERWRITTEN;
1219
info = FILE_WAS_CREATED;
1227
* Setup the oplock info in both the shared memory and
1231
if ((fsp->oplock_type != NO_OPLOCK) &&
1232
(fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1233
if (!set_file_oplock(fsp, fsp->oplock_type)) {
1234
/* Could not get the kernel oplock */
1235
fsp->oplock_type = NO_OPLOCK;
1239
if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1240
(!lp_level2_oplocks(SNUM(conn)) ||
1241
!(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1243
DEBUG(5, ("Downgrading level2 oplock on open "
1244
"because level2 oplocks = off\n"));
1246
release_file_oplock(fsp);
1249
if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1250
info == FILE_WAS_SUPERSEDED) {
1251
new_file_created = True;
1254
set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1257
/* Handle strange delete on close create semantics. */
1258
if (create_options & FILE_DELETE_ON_CLOSE) {
1259
status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1261
if (!NT_STATUS_IS_OK(status)) {
1262
/* Remember to delete the mode we just added. */
1263
del_share_mode(lck, fsp);
1268
/* Note that here we set the *inital* delete on close flag,
1269
not the regular one. The magic gets handled in close. */
1270
fsp->initial_delete_on_close = True;
1274
* Take care of inherited ACLs on created files - if default ACL not
1276
* May be necessary depending on acl policies.
1278
if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1279
&& (psbuf->st_flags & SF_HASNTFSACL))) {
1281
int saved_errno = errno; /* We might get ENOSYS in the next
1284
if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1286
errno = saved_errno; /* Ignore ENOSYS */
1289
} else if (new_unx_mode) {
1293
/* Attributes need changing. File already existed. */
1296
int saved_errno = errno; /* We might get ENOSYS in the
1298
ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1300
if (ret == -1 && errno == ENOSYS) {
1301
errno = saved_errno; /* Ignore ENOSYS */
1303
DEBUG(5, ("onefs_open_file_ntcreate: reset "
1304
"attributes of file %s to 0%o\n",
1305
fname, (unsigned int)new_unx_mode));
1306
ret = 0; /* Don't do the fchmod below. */
1311
(SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1312
DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1313
"attributes of file %s to 0%o\n",
1314
fname, (unsigned int)new_unx_mode));
1317
/* If this is a successful open, we must remove any deferred open
1320
del_deferred_open_entry(lck, req->mid);
1324
return NT_STATUS_OK;
1328
/****************************************************************************
1329
Open a directory from an NT SMB call.
1330
****************************************************************************/
1331
static NTSTATUS onefs_open_directory(connection_struct *conn,
1332
struct smb_request *req,
1335
uint32 share_access,
1336
uint32 create_disposition,
1337
uint32 create_options,
1338
uint32 file_attributes,
1339
struct security_descriptor *sd,
1340
files_struct **result,
1342
SMB_STRUCT_STAT *psbuf)
1344
files_struct *fsp = NULL;
1345
struct share_mode_lock *lck = NULL;
1347
struct timespec mtimespec;
1350
const char *dirname;
1351
bool posix_open = false;
1352
uint32 create_flags = 0;
1353
uint32 mode = lp_dir_mask(SNUM(conn));
1355
DEBUG(5, ("onefs_open_directory: opening directory %s, "
1356
"access_mask = 0x%x, "
1357
"share_access = 0x%x create_options = 0x%x, "
1358
"create_disposition = 0x%x, file_attributes = 0x%x\n",
1359
fname, (unsigned int)access_mask, (unsigned int)share_access,
1360
(unsigned int)create_options, (unsigned int)create_disposition,
1361
(unsigned int)file_attributes));
1363
if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1364
(conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1365
is_ntfs_stream_name(fname)) {
1366
DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1367
return NT_STATUS_NOT_A_DIRECTORY;
1370
switch (create_disposition) {
1372
/* If directory exists open. If directory doesn't
1375
info = FILE_WAS_OPENED;
1378
/* If directory exists error. If directory doesn't
1380
create_flags = O_CREAT | O_EXCL;
1381
info = FILE_WAS_CREATED;
1384
/* If directory exists open. If directory doesn't
1387
/* Note: in order to return whether the directory was
1388
* opened or created, we first try to open and then try
1391
info = FILE_WAS_OPENED;
1393
case FILE_SUPERSEDE:
1394
case FILE_OVERWRITE:
1395
case FILE_OVERWRITE_IF:
1397
DEBUG(5, ("onefs_open_directory: invalid "
1398
"create_disposition 0x%x for directory %s\n",
1399
(unsigned int)create_disposition, fname));
1400
return NT_STATUS_INVALID_PARAMETER;
1404
* Check for write access to the share. Done in mkdir_internal() in
1407
if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1408
return NT_STATUS_ACCESS_DENIED;
1411
/* Get parent dirname */
1412
if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
1413
return NT_STATUS_NO_MEMORY;
1416
if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1418
mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1419
file_attributes = 0;
1421
mode = unix_mode(conn, aDIR, fname, parent_dir);
1425
* The NONINDEXED and COMPRESSED bits seem to always be cleared on
1426
* directories, no matter if you specify that they should be set.
1429
~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1431
status = file_new(req, conn, &fsp);
1432
if(!NT_STATUS_IS_OK(status)) {
1437
* Actual open with retry magic to handle FILE_OPEN_IF which is
1438
* unique because the kernel won't tell us if the file was opened or
1442
fsp->fh->fd = onefs_sys_create_file(conn,
1449
create_flags | O_DIRECTORY,
1457
if (fsp->fh->fd == -1) {
1458
DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1460
SMB_ASSERT(errno != EINPROGRESS);
1462
if (create_disposition == FILE_OPEN_IF) {
1463
if (errno == ENOENT) {
1464
/* Try again, creating it this time. */
1465
create_flags = O_CREAT | O_EXCL;
1466
info = FILE_WAS_CREATED;
1468
} else if (errno == EEXIST) {
1469
/* Uggh. Try again again. */
1471
info = FILE_WAS_OPENED;
1476
/* Error cases below: */
1477
file_free(req, fsp);
1479
if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1480
DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1481
"for directory %s and it doesn't "
1482
"exist.\n", fname ));
1483
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1484
} else if ((errno == EEXIST) &&
1485
(create_disposition == FILE_CREATE)) {
1486
DEBUG(5,("onefs_open_directory: FILE_CREATE "
1487
"requested for directory %s and it "
1488
"already exists.\n", fname ));
1489
return NT_STATUS_OBJECT_NAME_COLLISION;
1490
} else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1491
/* Catch sharing violations. */
1492
return NT_STATUS_SHARING_VIOLATION;
1495
return map_nt_error_from_unix(errno);
1498
if (info == FILE_WAS_CREATED) {
1500
/* Pulled from mkdir_internal() */
1501
if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1502
DEBUG(2, ("Could not stat directory '%s' just "
1503
"created: %s\n",fname, strerror(errno)));
1504
return map_nt_error_from_unix(errno);
1507
if (!S_ISDIR(psbuf->st_mode)) {
1508
DEBUG(0, ("Directory just '%s' created is not a "
1509
"directory\n", fname));
1510
return NT_STATUS_ACCESS_DENIED;
1515
* Check if high bits should have been set, then (if
1516
* bits are missing): add them. Consider bits
1517
* automagically set by UNIX, i.e. SGID bit from
1520
if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1521
(mode & ~psbuf->st_mode)) {
1522
SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1523
(mode & ~psbuf->st_mode)));
1527
/* Change the owner if required. */
1528
if (lp_inherit_owner(SNUM(conn))) {
1529
change_dir_owner_to_parent(conn, parent_dir, fname,
1533
notify_fname(conn, NOTIFY_ACTION_ADDED,
1534
FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1537
/* Stat the fd for Samba bookkeeping. */
1538
if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1540
file_free(req, fsp);
1541
return map_nt_error_from_unix(errno);
1544
/* Setup the files_struct for it. */
1545
fsp->mode = psbuf->st_mode;
1546
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1547
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1548
fsp->file_pid = req ? req->smbpid : 0;
1549
fsp->can_lock = False;
1550
fsp->can_read = False;
1551
fsp->can_write = False;
1553
fsp->share_access = share_access;
1554
fsp->fh->private_options = create_options;
1556
* According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1558
fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1559
fsp->print_file = False;
1560
fsp->modified = False;
1561
fsp->oplock_type = NO_OPLOCK;
1562
fsp->sent_oplock_break = NO_BREAK_SENT;
1563
fsp->is_directory = True;
1564
fsp->posix_open = posix_open;
1566
string_set(&fsp->fsp_name,fname);
1568
mtimespec = get_mtimespec(psbuf);
1571
* Still set the samba share mode lock for correct delete-on-close
1572
* semantics and to make smbstatus more useful.
1574
lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1579
DEBUG(0, ("onefs_open_directory: Could not get share mode "
1580
"lock for %s\n", fname));
1582
file_free(req, fsp);
1583
return NT_STATUS_SHARING_VIOLATION;
1586
if (lck->delete_on_close) {
1589
file_free(req, fsp);
1590
return NT_STATUS_DELETE_PENDING;
1593
set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1596
* For directories the delete on close bit at open time seems
1597
* always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1599
if (create_options & FILE_DELETE_ON_CLOSE) {
1600
status = can_set_delete_on_close(fsp, True, 0);
1601
if (!NT_STATUS_IS_OK(status) &&
1602
!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1605
file_free(req, fsp);
1609
if (NT_STATUS_IS_OK(status)) {
1610
/* Note that here we set the *inital* delete on close flag,
1611
not the regular one. The magic gets handled in close. */
1612
fsp->initial_delete_on_close = True;
1623
return NT_STATUS_OK;
1627
* Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1629
static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1630
struct smb_request *req,
1632
uint32_t access_mask,
1633
uint32_t share_access,
1634
uint32_t create_disposition,
1635
uint32_t create_options,
1636
uint32_t file_attributes,
1637
uint32_t oplock_request,
1638
uint64_t allocation_size,
1639
struct security_descriptor *sd,
1640
struct ea_list *ea_list,
1641
files_struct **result,
1643
struct onefs_fsp_data *fsp_data,
1644
SMB_STRUCT_STAT *psbuf)
1646
SMB_STRUCT_STAT sbuf;
1647
int info = FILE_WAS_OPENED;
1648
files_struct *base_fsp = NULL;
1649
files_struct *fsp = NULL;
1652
DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1653
"file_attributes = 0x%x, share_access = 0x%x, "
1654
"create_disposition = 0x%x create_options = 0x%x "
1655
"oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1657
(unsigned int)access_mask,
1658
(unsigned int)file_attributes,
1659
(unsigned int)share_access,
1660
(unsigned int)create_disposition,
1661
(unsigned int)create_options,
1662
(unsigned int)oplock_request,
1663
ea_list, sd, fname));
1665
if (create_options & FILE_OPEN_BY_FILE_ID) {
1666
status = NT_STATUS_NOT_SUPPORTED;
1670
if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1671
status = NT_STATUS_INVALID_PARAMETER;
1676
SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1678
oplock_request |= INTERNAL_OPEN_ONLY;
1681
if (psbuf != NULL) {
1685
if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1686
SET_STAT_INVALID(sbuf);
1690
if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1691
PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1692
access_mask &= ~SYSTEM_SECURITY_ACCESS;
1695
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1696
&& (access_mask & DELETE_ACCESS)
1697
&& !is_ntfs_stream_name(fname)) {
1699
* We can't open a file with DELETE access if any of the
1700
* streams is open without FILE_SHARE_DELETE
1702
status = open_streams_for_delete(conn, fname);
1704
if (!NT_STATUS_IS_OK(status)) {
1709
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1710
&& is_ntfs_stream_name(fname)) {
1712
uint32 base_create_disposition;
1714
if (create_options & FILE_DIRECTORY_FILE) {
1715
status = NT_STATUS_NOT_A_DIRECTORY;
1719
status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
1721
if (!NT_STATUS_IS_OK(status)) {
1722
DEBUG(10, ("onefs_create_file_unixpath: "
1723
"split_ntfs_stream_name failed: %s\n",
1724
nt_errstr(status)));
1728
SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1730
switch (create_disposition) {
1732
base_create_disposition = FILE_OPEN;
1735
base_create_disposition = FILE_OPEN_IF;
1739
status = onefs_create_file_unixpath(
1743
SYNCHRONIZE_ACCESS, /* access_mask */
1746
FILE_SHARE_DELETE), /* share_access */
1747
base_create_disposition, /* create_disposition*/
1748
0, /* create_options */
1749
file_attributes, /* file_attributes */
1750
NO_OPLOCK, /* oplock_request */
1751
0, /* allocation_size */
1754
&base_fsp, /* result */
1756
NULL, /* fsp_data */
1759
if (!NT_STATUS_IS_OK(status)) {
1760
DEBUG(10, ("onefs_create_file_unixpath for base %s "
1761
"failed: %s\n", base, nt_errstr(status)));
1766
* Testing against windows xp/2003/vista shows that oplocks
1767
* can actually be requested and granted on streams (see the
1768
* RAW-OPLOCK-STREAM1 smbtorture test).
1770
if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1772
DEBUG(5, ("Oplock(%d) being requested on a stream! "
1773
"Ignoring oplock request: fname=%s\n",
1774
oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1776
/* Request NO_OPLOCK instead. */
1777
oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1781
/* Covert generic bits in the security descriptor. */
1783
security_acl_map_generic(sd->dacl, &file_generic_mapping);
1784
security_acl_map_generic(sd->sacl, &file_generic_mapping);
1788
* If it's a request for a directory open, deal with it separately.
1791
if (create_options & FILE_DIRECTORY_FILE) {
1793
if (create_options & FILE_NON_DIRECTORY_FILE) {
1794
status = NT_STATUS_INVALID_PARAMETER;
1798
/* Can't open a temp directory. IFS kit test. */
1799
if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1800
(file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1801
status = NT_STATUS_INVALID_PARAMETER;
1806
* We will get a create directory here if the Win32
1807
* app specified a security descriptor in the
1808
* CreateDirectory() call.
1811
status = onefs_open_directory(
1815
access_mask, /* access_mask */
1816
share_access, /* share_access */
1817
create_disposition, /* create_disposition*/
1818
create_options, /* create_options */
1819
file_attributes, /* file_attributes */
1827
* Ordinary file case.
1830
status = file_new(req, conn, &fsp);
1831
if(!NT_STATUS_IS_OK(status)) {
1836
* We're opening the stream element of a base_fsp
1837
* we already opened. Set up the base_fsp pointer.
1840
fsp->base_fsp = base_fsp;
1843
status = onefs_open_file_ntcreate(
1847
access_mask, /* access_mask */
1848
share_access, /* share_access */
1849
create_disposition, /* create_disposition*/
1850
create_options, /* create_options */
1851
file_attributes, /* file_attributes */
1852
oplock_request, /* oplock_request */
1856
fsp_data, /* fsp_data */
1859
if(!NT_STATUS_IS_OK(status)) {
1860
file_free(req, fsp);
1864
if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1866
/* A stream open never opens a directory */
1869
status = NT_STATUS_FILE_IS_A_DIRECTORY;
1874
* Fail the open if it was explicitly a non-directory
1878
if (create_options & FILE_NON_DIRECTORY_FILE) {
1879
status = NT_STATUS_FILE_IS_A_DIRECTORY;
1883
create_options |= FILE_DIRECTORY_FILE;
1885
status = onefs_open_directory(
1889
access_mask, /* access_mask */
1890
share_access, /* share_access */
1891
create_disposition, /* create_disposition*/
1892
create_options, /* create_options */
1893
file_attributes, /* file_attributes */
1901
if (!NT_STATUS_IS_OK(status)) {
1905
fsp->base_fsp = base_fsp;
1909
if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1910
status = set_ea(conn, fsp, fname, ea_list);
1911
if (!NT_STATUS_IS_OK(status)) {
1916
if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
1917
status = NT_STATUS_ACCESS_DENIED;
1921
/* Save the requested allocation size. */
1922
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1924
&& (allocation_size > sbuf.st_size)) {
1925
fsp->initial_allocation_size = smb_roundup(
1926
fsp->conn, allocation_size);
1927
if (fsp->is_directory) {
1928
/* Can't set allocation size on a directory. */
1929
status = NT_STATUS_ACCESS_DENIED;
1932
if (vfs_allocate_file_space(
1933
fsp, fsp->initial_allocation_size) == -1) {
1934
status = NT_STATUS_DISK_FULL;
1938
fsp->initial_allocation_size = smb_roundup(
1939
fsp->conn, (uint64_t)sbuf.st_size);
1943
DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1946
if (pinfo != NULL) {
1949
if (psbuf != NULL) {
1950
if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1954
SMB_VFS_FSTAT(fsp, psbuf);
1957
return NT_STATUS_OK;
1960
DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1963
if (base_fsp && fsp->base_fsp == base_fsp) {
1965
* The close_file below will close
1970
close_file(req, fsp, ERROR_CLOSE);
1973
if (base_fsp != NULL) {
1974
close_file(req, base_fsp, ERROR_CLOSE);
1980
static void destroy_onefs_fsp_data(void *p_data)
1982
struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
1984
destroy_onefs_callback_record(fsp_data->oplock_callback_id);
1988
* SMB_VFS_CREATE_FILE interface to onefs.
1990
NTSTATUS onefs_create_file(vfs_handle_struct *handle,
1991
struct smb_request *req,
1992
uint16_t root_dir_fid,
1994
uint32_t create_file_flags,
1995
uint32_t access_mask,
1996
uint32_t share_access,
1997
uint32_t create_disposition,
1998
uint32_t create_options,
1999
uint32_t file_attributes,
2000
uint32_t oplock_request,
2001
uint64_t allocation_size,
2002
struct security_descriptor *sd,
2003
struct ea_list *ea_list,
2004
files_struct **result,
2006
SMB_STRUCT_STAT *psbuf)
2008
connection_struct *conn = handle->conn;
2009
struct case_semantics_state *case_state = NULL;
2010
struct onefs_fsp_data fsp_data = {};
2011
SMB_STRUCT_STAT sbuf;
2012
int info = FILE_WAS_OPENED;
2013
files_struct *fsp = NULL;
2016
DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2017
"file_attributes = 0x%x, share_access = 0x%x, "
2018
"create_disposition = 0x%x create_options = 0x%x "
2019
"oplock_request = 0x%x "
2020
"root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2021
"create_file_flags = 0x%x, fname = %s\n",
2022
(unsigned int)access_mask,
2023
(unsigned int)file_attributes,
2024
(unsigned int)share_access,
2025
(unsigned int)create_disposition,
2026
(unsigned int)create_options,
2027
(unsigned int)oplock_request,
2028
(unsigned int)root_dir_fid,
2029
ea_list, sd, create_file_flags, fname));
2031
/* Get the file name if root_dir_fid was specified. */
2032
if (root_dir_fid != 0) {
2035
status = get_relative_fid_filename(conn, req, root_dir_fid,
2037
if (!NT_STATUS_IS_OK(status)) {
2044
/* Resolve the file name if this was a DFS pathname. */
2045
if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2046
char *resolved_fname;
2048
status = resolve_dfspath(talloc_tos(), conn, true, fname,
2051
if (!NT_STATUS_IS_OK(status)) {
2053
* For PATH_NOT_COVERED we had
2054
* reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2055
* ERRSRV, ERRbadpath);
2056
* Need to fix in callers
2060
fname = resolved_fname;
2063
/* Check if POSIX semantics are wanted. */
2064
if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2065
case_state = set_posix_case_semantics(talloc_tos(), conn);
2068
/* Convert dos path to unix path if it hasn't already been done. */
2069
if (create_file_flags & CFF_DOS_PATH) {
2070
char *converted_fname;
2072
SET_STAT_INVALID(sbuf);
2074
status = unix_convert(talloc_tos(), conn, fname, False,
2075
&converted_fname, NULL, &sbuf);
2076
if (!NT_STATUS_IS_OK(status)) {
2079
fname = converted_fname;
2081
if (psbuf != NULL) {
2084
if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2085
SET_STAT_INVALID(sbuf);
2091
TALLOC_FREE(case_state);
2093
/* All file access must go through check_name() */
2094
status = check_name(conn, fname);
2095
if (!NT_STATUS_IS_OK(status)) {
2099
status = onefs_create_file_unixpath(
2103
access_mask, /* access_mask */
2104
share_access, /* share_access */
2105
create_disposition, /* create_disposition*/
2106
create_options, /* create_options */
2107
file_attributes, /* file_attributes */
2108
oplock_request, /* oplock_request */
2109
allocation_size, /* allocation_size */
2111
ea_list, /* ea_list */
2114
&fsp_data, /* fsp_data */
2117
if (!NT_STATUS_IS_OK(status)) {
2121
DEBUG(10, ("onefs_create_file: info=%d\n", info));
2124
* Setup private onefs_fsp_data. Currently the private data struct is
2125
* only used to store the oplock_callback_id so that when the file is
2126
* closed, the onefs_callback_record can be properly cleaned up in the
2127
* oplock_onefs sub-system.
2130
struct onefs_fsp_data *fsp_data_tmp = NULL;
2131
fsp_data_tmp = (struct onefs_fsp_data *)
2132
VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2133
&destroy_onefs_fsp_data);
2135
if (fsp_data_tmp == NULL) {
2136
status = NT_STATUS_NO_MEMORY;
2140
*fsp_data_tmp = fsp_data;
2144
if (pinfo != NULL) {
2147
if (psbuf != NULL) {
2150
return NT_STATUS_OK;
2153
DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2156
close_file(req, fsp, ERROR_CLOSE);