~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/modules/onefs_open.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Unix SMB/CIFS implementation.
 
3
 *
 
4
 * This file began with some code from source3/smbd/open.c and has been
 
5
 * modified it work with ifs_createfile.
 
6
 *
 
7
 * ifs_createfile is a CIFS-specific syscall for opening/files and
 
8
 * directories.  It adds support for:
 
9
 *    - Full in-kernel access checks using a windows access_mask
 
10
 *    - Cluster-coherent share mode locks
 
11
 *    - Cluster-coherent oplocks
 
12
 *    - Streams
 
13
 *    - Setting security descriptors at create time
 
14
 *    - Setting dos_attributes at create time
 
15
 *
 
16
 * Copyright (C) Andrew Tridgell 1992-1998
 
17
 * Copyright (C) Jeremy Allison 2001-2004
 
18
 * Copyright (C) Volker Lendecke 2005
 
19
 * Copyright (C) Tim Prouty, 2008
 
20
 *
 
21
 * This program is free software; you can redistribute it and/or modify
 
22
 * it under the terms of the GNU General Public License as published by
 
23
 * the Free Software Foundation; either version 3 of the License, or
 
24
 * (at your option) any later version.
 
25
 *
 
26
 * This program is distributed in the hope that it will be useful,
 
27
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
28
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
29
 * GNU General Public License for more details.
 
30
 *
 
31
 * You should have received a copy of the GNU General Public License
 
32
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 
33
 */
 
34
 
 
35
#include "includes.h"
 
36
#include "onefs.h"
 
37
#include "onefs_config.h"
 
38
#include "oplock_onefs.h"
 
39
#include "smbd/globals.h"
 
40
 
 
41
extern const struct generic_mapping file_generic_mapping;
 
42
 
 
43
struct onefs_fsp_data {
 
44
        uint64_t oplock_callback_id;
 
45
};
 
46
 
 
47
static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
 
48
                              struct smb_request *req,
 
49
                              const char *fname,
 
50
                              uint32_t access_mask,
 
51
                              uint32_t share_access,
 
52
                              uint32_t create_disposition,
 
53
                              uint32_t create_options,
 
54
                              uint32_t file_attributes,
 
55
                              uint32_t oplock_request,
 
56
                              uint64_t allocation_size,
 
57
                              struct security_descriptor *sd,
 
58
                              struct ea_list *ea_list,
 
59
                              files_struct **result,
 
60
                              int *pinfo,
 
61
                              struct onefs_fsp_data *fsp_data,
 
62
                              SMB_STRUCT_STAT *psbuf);
 
63
 
 
64
/****************************************************************************
 
65
 Open a file.
 
66
****************************************************************************/
 
67
 
 
68
static NTSTATUS onefs_open_file(files_struct *fsp,
 
69
                                connection_struct *conn,
 
70
                                struct smb_request *req,
 
71
                                const char *parent_dir,
 
72
                                const char *name,
 
73
                                const char *path,
 
74
                                SMB_STRUCT_STAT *psbuf,
 
75
                                int flags,
 
76
                                mode_t unx_mode,
 
77
                                uint32 access_mask,
 
78
                                uint32 open_access_mask,
 
79
                                int oplock_request,
 
80
                                uint64 id,
 
81
                                uint32 share_access,
 
82
                                uint32 create_options,
 
83
                                uint32_t new_dos_attributes,
 
84
                                struct security_descriptor *sd,
 
85
                                int *granted_oplock)
 
86
{
 
87
        NTSTATUS status = NT_STATUS_OK;
 
88
        int accmode = (flags & O_ACCMODE);
 
89
        int local_flags = flags;
 
90
        bool file_existed = VALID_STAT(*psbuf);
 
91
        const char *wild;
 
92
        char *base = NULL;
 
93
        char *stream = NULL;
 
94
        int base_fd = -1;
 
95
 
 
96
        fsp->fh->fd = -1;
 
97
        errno = EPERM;
 
98
 
 
99
        /* Check permissions */
 
100
 
 
101
        /*
 
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.
 
108
         * JRA.
 
109
         */
 
110
 
 
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.
 
120
                        */
 
121
                        flags &= ~O_CREAT;
 
122
                        local_flags &= ~O_CREAT;
 
123
                }
 
124
        }
 
125
 
 
126
        /*
 
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.
 
136
         */
 
137
 
 
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;
 
142
        }
 
143
 
 
144
#if defined(O_NONBLOCK) && defined(S_ISFIFO)
 
145
        /*
 
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
 
148
         * open flags. JRA.
 
149
         */
 
150
 
 
151
        if (file_existed && S_ISFIFO(psbuf->st_mode)) {
 
152
                local_flags |= O_NONBLOCK;
 
153
        }
 
154
#endif
 
155
 
 
156
        /* Don't create files with Microsoft wildcard characters. */
 
157
        if (fsp->base_fsp) {
 
158
                /*
 
159
                 * wildcard characters are allowed in stream names
 
160
                 * only test the basefilename
 
161
                 */
 
162
                wild = fsp->base_fsp->fsp_name;
 
163
        } else {
 
164
                wild = path;
 
165
        }
 
166
        if ((local_flags & O_CREAT) && !file_existed &&
 
167
            ms_has_wild(wild))  {
 
168
                /*
 
169
                 * XXX: may need to remvoe this return...
 
170
                 *
 
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.
 
175
                 */
 
176
                DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
 
177
                          path));
 
178
                return NT_STATUS_OBJECT_NAME_INVALID;
 
179
        }
 
180
 
 
181
        /* Actually do the open */
 
182
 
 
183
#ifdef O_NOFOLLOW
 
184
        /*
 
185
         * Never follow symlinks on a POSIX client. The
 
186
         * client should be doing this.
 
187
         */
 
188
 
 
189
        if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
 
190
                flags |= O_NOFOLLOW;
 
191
        }
 
192
#endif
 
193
        /* Stream handling */
 
194
        if (is_ntfs_stream_name(path)) {
 
195
                status = onefs_split_ntfs_stream_name(talloc_tos(), path,
 
196
                                                      &base, &stream);
 
197
        }
 
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);
 
201
 
 
202
                DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n",
 
203
                          base, fsp->base_fsp->fh->fd, stream));
 
204
 
 
205
                base_fd = fsp->base_fsp->fh->fd;
 
206
        }
 
207
 
 
208
        fsp->fh->fd = onefs_sys_create_file(conn,
 
209
                                            base_fd,
 
210
                                            stream != NULL ? stream :
 
211
                                            (base != NULL ? base : path),
 
212
                                            access_mask,
 
213
                                            open_access_mask,
 
214
                                            share_access,
 
215
                                            create_options,
 
216
                                            flags,
 
217
                                            unx_mode,
 
218
                                            oplock_request,
 
219
                                            id,
 
220
                                            sd,
 
221
                                            new_dos_attributes,
 
222
                                            granted_oplock);
 
223
 
 
224
        if (fsp->fh->fd == -1) {
 
225
                if (errno == EMFILE) {
 
226
                        static time_t last_warned = 0L;
 
227
 
 
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);
 
236
                        }
 
237
                }
 
238
 
 
239
                status = map_nt_error_from_unix(errno);
 
240
                DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
 
241
                        "(flags=%d)\n",
 
242
                        path, strerror(errno), local_flags, flags));
 
243
                return status;
 
244
        }
 
245
 
 
246
        if ((local_flags & O_CREAT) && !file_existed) {
 
247
 
 
248
                /* Inherit the ACL if required */
 
249
                if (lp_inherit_perms(SNUM(conn))) {
 
250
                        inherit_access_posix_acl(conn, parent_dir, path,
 
251
                            unx_mode);
 
252
                }
 
253
 
 
254
                /* Change the owner if required. */
 
255
                if (lp_inherit_owner(SNUM(conn))) {
 
256
                        change_file_owner_to_parent(conn, parent_dir,
 
257
                            fsp);
 
258
                }
 
259
 
 
260
                notify_fname(conn, NOTIFY_ACTION_ADDED,
 
261
                    FILE_NOTIFY_CHANGE_FILE_NAME, path);
 
262
        }
 
263
 
 
264
        if (!file_existed) {
 
265
                int ret;
 
266
 
 
267
                if (fsp->fh->fd == -1) {
 
268
                        ret = SMB_VFS_STAT(conn, path, psbuf);
 
269
                } else {
 
270
                        ret = SMB_VFS_FSTAT(fsp, psbuf);
 
271
                        /* If we have an fd, this stat should succeed. */
 
272
                        if (ret == -1) {
 
273
                                DEBUG(0,("Error doing fstat on open file %s "
 
274
                                         "(%s)\n", path,strerror(errno) ));
 
275
                        }
 
276
                }
 
277
 
 
278
                /* For a non-io open, this stat failing means file not found. JRA */
 
279
                if (ret == -1) {
 
280
                        status = map_nt_error_from_unix(errno);
 
281
                        fd_close(fsp);
 
282
                        return status;
 
283
                }
 
284
        }
 
285
 
 
286
        /*
 
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.
 
290
         */
 
291
 
 
292
        if(S_ISDIR(psbuf->st_mode)) {
 
293
                fd_close(fsp);
 
294
                errno = EISDIR;
 
295
                return NT_STATUS_FILE_IS_A_DIRECTORY;
 
296
        }
 
297
 
 
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;
 
306
        } else {
 
307
                fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
 
308
                        True : False;
 
309
        }
 
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;
 
317
        }
 
318
 
 
319
        string_set(&fsp->fsp_name, path);
 
320
        fsp->wcp = NULL; /* Write cache pointer. */
 
321
 
 
322
        DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
 
323
                 conn->server_info->unix_name,
 
324
                 fsp->fsp_name,
 
325
                 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
 
326
                 conn->num_files_open));
 
327
 
 
328
        errno = 0;
 
329
        return NT_STATUS_OK;
 
330
}
 
331
 
 
332
/****************************************************************************
 
333
 Handle the 1 second delay in returning a SHARING_VIOLATION error.
 
334
****************************************************************************/
 
335
 
 
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)
 
341
{
 
342
        int i;
 
343
 
 
344
        /* Paranoia check */
 
345
 
 
346
        for (i=0; i<lck->num_share_modes; i++) {
 
347
                struct share_mode_entry *e = &lck->share_modes[i];
 
348
 
 
349
                if (!is_deferred_open_entry(e)) {
 
350
                        continue;
 
351
                }
 
352
 
 
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");
 
357
                }
 
358
        }
 
359
 
 
360
        /* End paranoia check */
 
361
 
 
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));
 
367
 
 
368
        if (!push_deferred_smb_message(req, request_time, timeout,
 
369
                                       (char *)state, sizeof(*state))) {
 
370
                exit_server("push_deferred_smb_message failed");
 
371
        }
 
372
        add_deferred_open(lck, req->mid, request_time, state->id);
 
373
 
 
374
        /*
 
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.
 
379
         */
 
380
 
 
381
        srv_defer_sign_response(req->mid);
 
382
}
 
383
 
 
384
static void schedule_defer_open(struct share_mode_lock *lck,
 
385
                                struct timeval request_time,
 
386
                                struct smb_request *req)
 
387
{
 
388
        struct deferred_open_record state;
 
389
 
 
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. */
 
397
 
 
398
        struct timeval timeout;
 
399
 
 
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
 
404
         * somewhere else. */
 
405
 
 
406
        /*
 
407
         * On OneFS, the kernel will always send an oplock_revoked message
 
408
         * before this timeout is hit.
 
409
         */
 
410
        timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
 
411
 
 
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. */
 
416
 
 
417
        state.delayed_for_oplocks = True;
 
418
        state.failed = false;
 
419
        state.id = lck->id;
 
420
 
 
421
        if (!request_timed_out(request_time, timeout)) {
 
422
                defer_open(lck, request_time, timeout, req, &state);
 
423
        }
 
424
}
 
425
 
 
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,
 
431
                                  const char *fname,
 
432
                                  uint32 access_mask,
 
433
                                  uint32 share_access,
 
434
                                  uint32 create_disposition,
 
435
                                  uint32 create_options,
 
436
                                  uint32 new_dos_attributes,
 
437
                                  int oplock_request,
 
438
                                  struct security_descriptor *sd,
 
439
                                  files_struct *fsp,
 
440
                                  int *pinfo,
 
441
                                  struct onefs_fsp_data *fsp_data,
 
442
                                  SMB_STRUCT_STAT *psbuf)
 
443
{
 
444
        int flags=0;
 
445
        int flags2=0;
 
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;
 
451
        struct file_id id;
 
452
        mode_t new_unx_mode = (mode_t)0;
 
453
        mode_t unx_mode = (mode_t)0;
 
454
        int info;
 
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;
 
460
        NTSTATUS status;
 
461
        int ret_flock;
 
462
        char *parent_dir;
 
463
        const char *newname;
 
464
        int granted_oplock;
 
465
        uint64_t oplock_callback_id = 0;
 
466
        uint32 createfile_attributes = 0;
 
467
 
 
468
        ZERO_STRUCT(id);
 
469
 
 
470
        if (conn->printer) {
 
471
                /*
 
472
                 * Printers are handled completely differently.
 
473
                 * Most of the passed parameters are ignored.
 
474
                 */
 
475
 
 
476
                if (pinfo) {
 
477
                        *pinfo = FILE_WAS_CREATED;
 
478
                }
 
479
 
 
480
                DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
 
481
                          fname));
 
482
 
 
483
                return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
 
484
        }
 
485
 
 
486
        if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
 
487
                return NT_STATUS_NO_MEMORY;
 
488
        }
 
489
 
 
490
        if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
 
491
                posix_open = True;
 
492
                unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
 
493
                new_dos_attributes = 0;
 
494
        } else {
 
495
                /* We add aARCH to this as this mode is only used if the file is
 
496
                 * created new. */
 
497
                unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
 
498
                                     parent_dir);
 
499
        }
 
500
 
 
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,
 
507
                  oplock_request));
 
508
 
 
509
        /*
 
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:
 
514
         *
 
515
         *   1. Open the base file of a stream: Always done stat-only
 
516
         *
 
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
 
524
         *         bad.
 
525
         */
 
526
        if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
 
527
                smb_panic("NULL req on a non-stat-open!");
 
528
        }
 
529
 
 
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;
 
533
        }
 
534
 
 
535
        /*
 
536
         * Only non-internal opens can be deferred at all
 
537
         */
 
538
 
 
539
        if ((req != NULL)
 
540
            && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
 
541
                struct deferred_open_record *state =
 
542
                        (struct deferred_open_record *)pml->private_data.data;
 
543
 
 
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. */
 
547
 
 
548
                request_time = pml->request_time;
 
549
 
 
550
                /* Remove the deferred open entry under lock. */
 
551
                lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
 
552
                                          NULL);
 
553
                if (lck == NULL) {
 
554
                        DEBUG(0, ("could not get share mode lock\n"));
 
555
                } else {
 
556
                        del_deferred_open_entry(lck, req->mid);
 
557
                        TALLOC_FREE(lck);
 
558
                }
 
559
 
 
560
                /* Ensure we don't reprocess this message. */
 
561
                remove_deferred_open_smb_message(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
        status = check_name(conn, fname);
 
576
        if (!NT_STATUS_IS_OK(status)) {
 
577
                return status;
 
578
        }
 
579
 
 
580
        if (!posix_open) {
 
581
                new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
 
582
                if (file_existed) {
 
583
                        existing_dos_attributes = dos_mode(conn, fname, psbuf);
 
584
                }
 
585
        }
 
586
 
 
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);
 
591
        }
 
592
 
 
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;
 
598
        }
 
599
 
 
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
 
603
                 * release. */
 
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;
 
608
                }
 
609
                return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
 
610
        }
 
611
 
 
612
        switch( create_disposition ) {
 
613
                /*
 
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.
 
618
                 */
 
619
                case FILE_SUPERSEDE:
 
620
                        /**
 
621
                         * @todo: Clear all file attributes?
 
622
                         * http://www.osronline.com/article.cfm?article=302
 
623
                         * create if not exist, trunc if exist
 
624
                         *
 
625
                         * If file exists replace/overwrite. If file doesn't
 
626
                         * exist create.
 
627
                         */
 
628
                        flags2 |= (O_CREAT | O_TRUNC);
 
629
                        clear_ads = true;
 
630
                        break;
 
631
 
 
632
                case FILE_OVERWRITE_IF:
 
633
                        /* If file exists replace/overwrite. If file doesn't
 
634
                         * exist create. */
 
635
                        flags2 |= (O_CREAT | O_TRUNC);
 
636
                        clear_ads = true;
 
637
                        break;
 
638
 
 
639
                case FILE_OPEN:
 
640
                        /* If file exists open. If file doesn't exist error. */
 
641
                        if (!file_existed) {
 
642
                                DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
 
643
                                         "requested for file %s and file "
 
644
                                         "doesn't exist.\n", fname ));
 
645
                                errno = ENOENT;
 
646
                                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 
647
                        }
 
648
                        break;
 
649
 
 
650
                case FILE_OVERWRITE:
 
651
                        /* If file exists overwrite. If file doesn't exist
 
652
                         * error. */
 
653
                        if (!file_existed) {
 
654
                                DEBUG(5, ("onefs_open_file_ntcreate: "
 
655
                                          "FILE_OVERWRITE requested for file "
 
656
                                          "%s and file doesn't exist.\n",
 
657
                                          fname));
 
658
                                errno = ENOENT;
 
659
                                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 
660
                        }
 
661
                        flags2 |= O_TRUNC;
 
662
                        clear_ads = true;
 
663
                        break;
 
664
 
 
665
                case FILE_CREATE:
 
666
                        /* If file exists error. If file doesn't exist
 
667
                         * create. */
 
668
                        if (file_existed) {
 
669
                                DEBUG(5, ("onefs_open_file_ntcreate: "
 
670
                                          "FILE_CREATE requested for file %s "
 
671
                                          "and file already exists.\n",
 
672
                                          fname));
 
673
                                if (S_ISDIR(psbuf->st_mode)) {
 
674
                                        errno = EISDIR;
 
675
                                } else {
 
676
                                        errno = EEXIST;
 
677
                                }
 
678
                                return map_nt_error_from_unix(errno);
 
679
                        }
 
680
                        flags2 |= (O_CREAT|O_EXCL);
 
681
                        break;
 
682
 
 
683
                case FILE_OPEN_IF:
 
684
                        /* If file exists open. If file doesn't exist
 
685
                         * create. */
 
686
                        flags2 |= O_CREAT;
 
687
                        break;
 
688
 
 
689
                default:
 
690
                        return NT_STATUS_INVALID_PARAMETER;
 
691
        }
 
692
 
 
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,
 
704
                                  new_dos_attributes,
 
705
                                  (unsigned int)psbuf->st_mode,
 
706
                                  (unsigned int)unx_mode ));
 
707
                        errno = EACCES;
 
708
                        return NT_STATUS_ACCESS_DENIED;
 
709
                }
 
710
        }
 
711
 
 
712
        /*
 
713
         * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
 
714
         * access_mask, but leave the MAA for the actual open in
 
715
         * open_access_mask.
 
716
         */
 
717
        open_access_mask = access_mask;
 
718
        if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
 
719
                access_mask |= FILE_GENERIC_ALL;
 
720
        }
 
721
 
 
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);
 
725
 
 
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;
 
729
        }
 
730
 
 
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));
 
734
 
 
735
        /*
 
736
         * Note that we ignore the append flag as append does not
 
737
         * mean the same thing under DOS and Unix.
 
738
         */
 
739
 
 
740
        if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
 
741
            (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
 
742
 
 
743
                /*
 
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.
 
749
                 */
 
750
                if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
 
751
 
 
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));
 
757
 
 
758
                        flags = O_RDWR;
 
759
                        open_access_mask |= (FILE_READ_ATTRIBUTES |
 
760
                            FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
 
761
 
 
762
                } else if (access_mask & (FILE_READ_ATTRIBUTES |
 
763
                               FILE_READ_DATA |
 
764
                               FILE_READ_EA |
 
765
                               FILE_EXECUTE)) {
 
766
                        flags = O_RDWR;
 
767
                } else {
 
768
                        flags = O_WRONLY;
 
769
                }
 
770
        } else {
 
771
                flags = O_RDONLY;
 
772
        }
 
773
 
 
774
        /* Currently we only look at FILE_WRITE_THROUGH for create options. */
 
775
#if defined(O_SYNC)
 
776
        if ((create_options & FILE_WRITE_THROUGH) &&
 
777
            lp_strict_sync(SNUM(conn))) {
 
778
                flags2 |= O_SYNC;
 
779
        }
 
780
#endif /* O_SYNC */
 
781
 
 
782
        if (posix_open && (access_mask & FILE_APPEND_DATA)) {
 
783
                flags2 |= O_APPEND;
 
784
        }
 
785
 
 
786
        if (!posix_open && !CAN_WRITE(conn)) {
 
787
                /*
 
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.
 
791
                 */
 
792
                flags2 &= ~(O_CREAT|O_TRUNC);
 
793
 
 
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);
 
797
                }
 
798
        }
 
799
 
 
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" ));
 
806
                errno = EACCES;
 
807
                return NT_STATUS_ACCESS_DENIED;
 
808
        }
 
809
 
 
810
        DEBUG(10, ("fsp = %p\n", fsp));
 
811
 
 
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;
 
819
 
 
820
        /* Ensure no SAMBA_PRIVATE bits can be set. */
 
821
        fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
 
822
 
 
823
        if (timeval_is_zero(&request_time)) {
 
824
                request_time = fsp->open_time;
 
825
        }
 
826
 
 
827
        if (file_existed) {
 
828
                struct timespec old_write_time = get_mtimespec(psbuf);
 
829
                id = vfs_file_id_from_sbuf(conn, psbuf);
 
830
 
 
831
                lck = get_share_mode_lock(talloc_tos(), id,
 
832
                                          conn->connectpath,
 
833
                                          fname, &old_write_time);
 
834
 
 
835
                if (lck == NULL) {
 
836
                        DEBUG(0, ("Could not get share mode lock\n"));
 
837
                        return NT_STATUS_SHARING_VIOLATION;
 
838
                }
 
839
 
 
840
                if (lck->delete_on_close) {
 
841
                        /* DELETE_PENDING is not deferred for a second */
 
842
                        TALLOC_FREE(lck);
 
843
                        return NT_STATUS_DELETE_PENDING;
 
844
                }
 
845
        }
 
846
 
 
847
        SMB_ASSERT(!file_existed || (lck != NULL));
 
848
 
 
849
        /*
 
850
         * Ensure we pay attention to default ACLs on directories.  May be
 
851
         * neccessary depending on ACL policies.
 
852
         */
 
853
        if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
 
854
            (def_acl = directory_has_default_acl(conn, parent_dir))) {
 
855
                unx_mode = 0777;
 
856
        }
 
857
 
 
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));
 
863
 
 
864
        /*
 
865
         * Since the open is guaranteed to be stat only if req == NULL, a
 
866
         * callback record is only needed if req != NULL.
 
867
         */
 
868
        if (req) {
 
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;
 
873
                }
 
874
        } else {
 
875
                /*
 
876
                 * It is also already asserted it's either a stream or a
 
877
                 * stat-only open at this point.
 
878
                 */
 
879
                SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
 
880
        }
 
881
 
 
882
        /* Do the open. */
 
883
        status = onefs_open_file(fsp,
 
884
                                 conn,
 
885
                                 req,
 
886
                                 parent_dir,
 
887
                                 newname,
 
888
                                 fname,
 
889
                                 psbuf,
 
890
                                 flags|flags2,
 
891
                                 unx_mode,
 
892
                                 access_mask,
 
893
                                 open_access_mask,
 
894
                                 fsp->oplock_type,
 
895
                                 oplock_callback_id,
 
896
                                 share_access,
 
897
                                 create_options,
 
898
                                 createfile_attributes,
 
899
                                 sd,
 
900
                                 &granted_oplock);
 
901
 
 
902
        if (!NT_STATUS_IS_OK(status)) {
 
903
 
 
904
                /* OneFS Oplock Handling */
 
905
                if (errno == EINPROGRESS) {
 
906
 
 
907
                        if (lck == NULL) {
 
908
 
 
909
                                struct deferred_open_record state;
 
910
                                struct timespec old_write_time;
 
911
 
 
912
                                old_write_time = get_mtimespec(psbuf);
 
913
 
 
914
                                DEBUG(3, ("Someone created file %s with an "
 
915
                                          "oplock after we looked: Retrying\n",
 
916
                                          fname));
 
917
                                /*
 
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.
 
922
                                 */
 
923
                                id = vfs_file_id_from_sbuf(conn, psbuf);
 
924
                                if (!(lck = get_share_mode_lock(talloc_tos(),
 
925
                                          id, conn->connectpath, fname,
 
926
                                          &old_write_time))) {
 
927
                                        /*
 
928
                                         * Emergency exit
 
929
                                         */
 
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;
 
935
                                }
 
936
 
 
937
                                state.delayed_for_oplocks = False;
 
938
                                state.id = id;
 
939
 
 
940
                                if (req != NULL) {
 
941
                                        defer_open(lck, request_time,
 
942
                                            timeval_zero(), req, &state);
 
943
                                }
 
944
                                goto cleanup_destroy;
 
945
                        }
 
946
                        /* Waiting for an oplock */
 
947
                        DEBUG(5,("Async createfile because a client has an "
 
948
                                 "oplock on %s\n", fname));
 
949
 
 
950
                        SMB_ASSERT(req);
 
951
                        schedule_defer_open(lck, request_time, req);
 
952
                        goto cleanup;
 
953
                }
 
954
 
 
955
                /* Check for a sharing violation */
 
956
                if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
 
957
                        uint32 can_access_mask;
 
958
                        bool can_access = True;
 
959
 
 
960
                        /* Check if this can be done with the deny_dos and fcb
 
961
                         * calls. */
 
962
 
 
963
                        /* Try to find dup fsp if possible. */
 
964
                        if (create_options &
 
965
                            (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
 
966
                             NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
 
967
 
 
968
                                if (req == NULL) {
 
969
                                        DEBUG(0, ("DOS open without an SMB "
 
970
                                                  "request!\n"));
 
971
                                        status = NT_STATUS_INTERNAL_ERROR;
 
972
                                        goto cleanup_destroy;
 
973
                                }
 
974
 
 
975
                                /* Use the client requested access mask here,
 
976
                                 * not the one we open with. */
 
977
                                status = fcb_or_dos_open(req,
 
978
                                                        conn,
 
979
                                                        fsp,
 
980
                                                        fname,
 
981
                                                        id,
 
982
                                                        req->smbpid,
 
983
                                                        req->vuid,
 
984
                                                        access_mask,
 
985
                                                        share_access,
 
986
                                                        create_options);
 
987
 
 
988
                                if (NT_STATUS_IS_OK(status)) {
 
989
                                        if (pinfo) {
 
990
                                                *pinfo = FILE_WAS_OPENED;
 
991
                                        }
 
992
                                        status =  NT_STATUS_OK;
 
993
                                        goto cleanup;
 
994
                                }
 
995
                        }
 
996
 
 
997
                        /*
 
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.
 
1005
                         */
 
1006
 
 
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;
 
1011
                        } else {
 
1012
                                can_access_mask = FILE_READ_DATA;
 
1013
                        }
 
1014
 
 
1015
                        if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
 
1016
                            !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
 
1017
                                can_access = False;
 
1018
                        }
 
1019
 
 
1020
                        /*
 
1021
                         * If we're returning a share violation, ensure we
 
1022
                         * cope with the braindead 1 second delay.
 
1023
                         */
 
1024
                        if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
 
1025
                            lp_defer_sharing_violations()) {
 
1026
                                struct timeval timeout;
 
1027
                                struct deferred_open_record state;
 
1028
                                int timeout_usecs;
 
1029
 
 
1030
                                /* this is a hack to speed up torture tests
 
1031
                                   in 'make test' */
 
1032
                                timeout_usecs = lp_parm_int(SNUM(conn),
 
1033
                                    "smbd","sharedelay",
 
1034
                                    SHARING_VIOLATION_USEC_WAIT);
 
1035
 
 
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. */
 
1045
 
 
1046
                                timeout = timeval_set(0, timeout_usecs);
 
1047
 
 
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. */
 
1053
 
 
1054
                                state.delayed_for_oplocks = False;
 
1055
                                state.id = id;
 
1056
                                state.failed = false;
 
1057
 
 
1058
                                if ((req != NULL)
 
1059
                                    && !request_timed_out(request_time,
 
1060
                                                          timeout)) {
 
1061
                                        defer_open(lck, request_time, timeout,
 
1062
                                                   req, &state);
 
1063
                                }
 
1064
                        }
 
1065
 
 
1066
                        if (can_access) {
 
1067
                                /*
 
1068
                                 * We have detected a sharing violation here
 
1069
                                 * so return the correct error code
 
1070
                                 */
 
1071
                                status = NT_STATUS_SHARING_VIOLATION;
 
1072
                        } else {
 
1073
                                status = NT_STATUS_ACCESS_DENIED;
 
1074
                        }
 
1075
 
 
1076
                        goto cleanup_destroy;
 
1077
                }
 
1078
 
 
1079
                /*
 
1080
                 * Normal error, for example EACCES
 
1081
                 */
 
1082
         cleanup_destroy:
 
1083
                if (oplock_callback_id != 0) {
 
1084
                        destroy_onefs_callback_record(oplock_callback_id);
 
1085
                }
 
1086
         cleanup:
 
1087
                TALLOC_FREE(lck);
 
1088
                return status;
 
1089
        }
 
1090
 
 
1091
        fsp->oplock_type = granted_oplock;
 
1092
 
 
1093
        if (oplock_callback_id != 0) {
 
1094
                onefs_set_oplock_callback(oplock_callback_id, fsp);
 
1095
                fsp_data->oplock_callback_id = oplock_callback_id;
 
1096
        } else {
 
1097
                SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
 
1098
        }
 
1099
 
 
1100
        if (!file_existed) {
 
1101
                struct timespec old_write_time = get_mtimespec(psbuf);
 
1102
                /*
 
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.
 
1108
                 */
 
1109
 
 
1110
                /*
 
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.
 
1115
                 */
 
1116
 
 
1117
                id = fsp->file_id;
 
1118
 
 
1119
                lck = get_share_mode_lock(talloc_tos(), id,
 
1120
                                          conn->connectpath,
 
1121
                                          fname, &old_write_time);
 
1122
 
 
1123
                if (lck == NULL) {
 
1124
                        DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
 
1125
                                  "share mode lock for %s\n", fname));
 
1126
                        fd_close(fsp);
 
1127
                        return NT_STATUS_SHARING_VIOLATION;
 
1128
                }
 
1129
 
 
1130
                if (lck->delete_on_close) {
 
1131
                        status = NT_STATUS_DELETE_PENDING;
 
1132
                }
 
1133
 
 
1134
                if (!NT_STATUS_IS_OK(status)) {
 
1135
                        struct deferred_open_record state;
 
1136
 
 
1137
                        fd_close(fsp);
 
1138
 
 
1139
                        state.delayed_for_oplocks = False;
 
1140
                        state.id = id;
 
1141
 
 
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
 
1147
                         * anybody... */
 
1148
 
 
1149
                        if (req != NULL) {
 
1150
                                defer_open(lck, request_time, timeval_zero(),
 
1151
                                           req, &state);
 
1152
                        }
 
1153
                        TALLOC_FREE(lck);
 
1154
                        return status;
 
1155
                }
 
1156
 
 
1157
                /*
 
1158
                 * We exit this block with the share entry *locked*.....
 
1159
                 */
 
1160
 
 
1161
        }
 
1162
 
 
1163
        SMB_ASSERT(lck != NULL);
 
1164
 
 
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)) {
 
1169
                        TALLOC_FREE(lck);
 
1170
                        fd_close(fsp);
 
1171
                        return status;
 
1172
                }
 
1173
        }
 
1174
 
 
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 */
 
1182
 
 
1183
        if (fsp->fh->fd != -1) {
 
1184
                ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
 
1185
                if(ret_flock == -1 ){
 
1186
 
 
1187
                        TALLOC_FREE(lck);
 
1188
                        fd_close(fsp);
 
1189
                        return NT_STATUS_SHARING_VIOLATION;
 
1190
                }
 
1191
        }
 
1192
 
 
1193
        /*
 
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.
 
1197
         */
 
1198
 
 
1199
        /* Record the options we were opened with. */
 
1200
        fsp->share_access = share_access;
 
1201
        fsp->fh->private_options = create_options;
 
1202
        /*
 
1203
         * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
 
1204
         */
 
1205
        fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
 
1206
 
 
1207
        if (file_existed) {
 
1208
                /* stat opens on existing files don't get oplocks. */
 
1209
                if (is_stat_open(open_access_mask)) {
 
1210
                        fsp->oplock_type = NO_OPLOCK;
 
1211
                }
 
1212
 
 
1213
                if (!(flags2 & O_TRUNC)) {
 
1214
                        info = FILE_WAS_OPENED;
 
1215
                } else {
 
1216
                        info = FILE_WAS_OVERWRITTEN;
 
1217
                }
 
1218
        } else {
 
1219
                info = FILE_WAS_CREATED;
 
1220
        }
 
1221
 
 
1222
        if (pinfo) {
 
1223
                *pinfo = info;
 
1224
        }
 
1225
 
 
1226
        /*
 
1227
         * Setup the oplock info in both the shared memory and
 
1228
         * file structs.
 
1229
         */
 
1230
 
 
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;
 
1236
                }
 
1237
        }
 
1238
 
 
1239
        if (fsp->oplock_type == LEVEL_II_OPLOCK &&
 
1240
            (!lp_level2_oplocks(SNUM(conn)) ||
 
1241
                !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
 
1242
 
 
1243
                DEBUG(5, ("Downgrading level2 oplock on open "
 
1244
                          "because level2 oplocks = off\n"));
 
1245
 
 
1246
                release_file_oplock(fsp);
 
1247
        }
 
1248
 
 
1249
        if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
 
1250
            info == FILE_WAS_SUPERSEDED) {
 
1251
                new_file_created = True;
 
1252
        }
 
1253
 
 
1254
        set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
 
1255
                       fsp->oplock_type);
 
1256
 
 
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);
 
1260
 
 
1261
                if (!NT_STATUS_IS_OK(status)) {
 
1262
                        /* Remember to delete the mode we just added. */
 
1263
                        del_share_mode(lck, fsp);
 
1264
                        TALLOC_FREE(lck);
 
1265
                        fd_close(fsp);
 
1266
                        return status;
 
1267
                }
 
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;
 
1271
        }
 
1272
 
 
1273
        /*
 
1274
         * Take care of inherited ACLs on created files - if default ACL not
 
1275
         * selected.
 
1276
         * May be necessary depending on acl policies.
 
1277
         */
 
1278
        if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
 
1279
                  && (psbuf->st_flags & SF_HASNTFSACL))) {
 
1280
 
 
1281
                int saved_errno = errno; /* We might get ENOSYS in the next
 
1282
                                          * call.. */
 
1283
 
 
1284
                if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
 
1285
                    errno == ENOSYS) {
 
1286
                        errno = saved_errno; /* Ignore ENOSYS */
 
1287
                }
 
1288
 
 
1289
        } else if (new_unx_mode) {
 
1290
 
 
1291
                int ret = -1;
 
1292
 
 
1293
                /* Attributes need changing. File already existed. */
 
1294
 
 
1295
                {
 
1296
                        int saved_errno = errno; /* We might get ENOSYS in the
 
1297
                                                  * next call.. */
 
1298
                        ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
 
1299
 
 
1300
                        if (ret == -1 && errno == ENOSYS) {
 
1301
                                errno = saved_errno; /* Ignore ENOSYS */
 
1302
                        } else {
 
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. */
 
1307
                        }
 
1308
                }
 
1309
 
 
1310
                if ((ret == -1) &&
 
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));
 
1315
        }
 
1316
 
 
1317
        /* If this is a successful open, we must remove any deferred open
 
1318
         * records. */
 
1319
        if (req != NULL) {
 
1320
                del_deferred_open_entry(lck, req->mid);
 
1321
        }
 
1322
        TALLOC_FREE(lck);
 
1323
 
 
1324
        return NT_STATUS_OK;
 
1325
}
 
1326
 
 
1327
 
 
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,
 
1333
                                     const char *fname,
 
1334
                                     uint32 access_mask,
 
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,
 
1341
                                     int *pinfo,
 
1342
                                     SMB_STRUCT_STAT *psbuf)
 
1343
{
 
1344
        files_struct *fsp = NULL;
 
1345
        struct share_mode_lock *lck = NULL;
 
1346
        NTSTATUS status;
 
1347
        struct timespec mtimespec;
 
1348
        int info = 0;
 
1349
        char *parent_dir;
 
1350
        const char *dirname;
 
1351
        bool posix_open = false;
 
1352
        uint32 create_flags = 0;
 
1353
        uint32 mode = lp_dir_mask(SNUM(conn));
 
1354
 
 
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));
 
1362
 
 
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;
 
1368
        }
 
1369
 
 
1370
        switch (create_disposition) {
 
1371
                case FILE_OPEN:
 
1372
                        /* If directory exists open. If directory doesn't
 
1373
                         * exist error. */
 
1374
                        create_flags = 0;
 
1375
                        info = FILE_WAS_OPENED;
 
1376
                        break;
 
1377
                case FILE_CREATE:
 
1378
                        /* If directory exists error. If directory doesn't
 
1379
                         * exist create. */
 
1380
                        create_flags = O_CREAT | O_EXCL;
 
1381
                        info = FILE_WAS_CREATED;
 
1382
                        break;
 
1383
                case FILE_OPEN_IF:
 
1384
                        /* If directory exists open. If directory doesn't
 
1385
                         * exist create. */
 
1386
 
 
1387
                        /* Note: in order to return whether the directory was
 
1388
                         * opened or created, we first try to open and then try
 
1389
                         * to create. */
 
1390
                        create_flags = 0;
 
1391
                        info = FILE_WAS_OPENED;
 
1392
                        break;
 
1393
                case FILE_SUPERSEDE:
 
1394
                case FILE_OVERWRITE:
 
1395
                case FILE_OVERWRITE_IF:
 
1396
                default:
 
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;
 
1401
        }
 
1402
 
 
1403
        /*
 
1404
         * Check for write access to the share. Done in mkdir_internal() in
 
1405
         * mainline samba.
 
1406
         */
 
1407
        if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
 
1408
                return NT_STATUS_ACCESS_DENIED;
 
1409
        }
 
1410
 
 
1411
        /* Get parent dirname */
 
1412
        if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
 
1413
                return NT_STATUS_NO_MEMORY;
 
1414
        }
 
1415
 
 
1416
        if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
 
1417
                posix_open = true;
 
1418
                mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
 
1419
                file_attributes = 0;
 
1420
        } else {
 
1421
                mode = unix_mode(conn, aDIR, fname, parent_dir);
 
1422
        }
 
1423
 
 
1424
        /*
 
1425
         * The NONINDEXED and COMPRESSED bits seem to always be cleared on
 
1426
         * directories, no matter if you specify that they should be set.
 
1427
         */
 
1428
        file_attributes &=
 
1429
            ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
 
1430
 
 
1431
        status = file_new(req, conn, &fsp);
 
1432
        if(!NT_STATUS_IS_OK(status)) {
 
1433
                return status;
 
1434
        }
 
1435
 
 
1436
        /*
 
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
 
1439
         * created.
 
1440
         */
 
1441
 retry_open:
 
1442
        fsp->fh->fd = onefs_sys_create_file(conn,
 
1443
                                            -1,
 
1444
                                            fname,
 
1445
                                            access_mask,
 
1446
                                            access_mask,
 
1447
                                            share_access,
 
1448
                                            create_options,
 
1449
                                            create_flags | O_DIRECTORY,
 
1450
                                            mode,
 
1451
                                            0,
 
1452
                                            0,
 
1453
                                            sd,
 
1454
                                            file_attributes,
 
1455
                                            NULL);
 
1456
 
 
1457
        if (fsp->fh->fd == -1) {
 
1458
                DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
 
1459
                          strerror(errno)));
 
1460
                SMB_ASSERT(errno != EINPROGRESS);
 
1461
 
 
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;
 
1467
                                goto retry_open;
 
1468
                        } else if (errno == EEXIST) {
 
1469
                                /* Uggh. Try again again. */
 
1470
                                create_flags = 0;
 
1471
                                info = FILE_WAS_OPENED;
 
1472
                                goto retry_open;
 
1473
                        }
 
1474
                }
 
1475
 
 
1476
                /* Error cases below: */
 
1477
                file_free(req, fsp);
 
1478
 
 
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;
 
1493
                }
 
1494
 
 
1495
                return map_nt_error_from_unix(errno);
 
1496
        }
 
1497
 
 
1498
        if (info == FILE_WAS_CREATED) {
 
1499
 
 
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);
 
1505
                }
 
1506
 
 
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;
 
1511
                }
 
1512
 
 
1513
                if (!posix_open) {
 
1514
                        /*
 
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
 
1518
                         * parent dir.
 
1519
                         */
 
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)));
 
1524
                        }
 
1525
                }
 
1526
 
 
1527
                /* Change the owner if required. */
 
1528
                if (lp_inherit_owner(SNUM(conn))) {
 
1529
                        change_dir_owner_to_parent(conn, parent_dir, fname,
 
1530
                                                   psbuf);
 
1531
                }
 
1532
 
 
1533
                notify_fname(conn, NOTIFY_ACTION_ADDED,
 
1534
                             FILE_NOTIFY_CHANGE_DIR_NAME, fname);
 
1535
        }
 
1536
 
 
1537
        /* Stat the fd for Samba bookkeeping. */
 
1538
        if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
 
1539
                fd_close(fsp);
 
1540
                file_free(req, fsp);
 
1541
                return map_nt_error_from_unix(errno);
 
1542
        }
 
1543
 
 
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;
 
1552
 
 
1553
        fsp->share_access = share_access;
 
1554
        fsp->fh->private_options = create_options;
 
1555
        /*
 
1556
         * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
 
1557
         */
 
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;
 
1565
 
 
1566
        string_set(&fsp->fsp_name,fname);
 
1567
 
 
1568
        mtimespec = get_mtimespec(psbuf);
 
1569
 
 
1570
        /*
 
1571
         * Still set the samba share mode lock for correct delete-on-close
 
1572
         * semantics and to make smbstatus more useful.
 
1573
         */
 
1574
        lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
 
1575
                                  conn->connectpath,
 
1576
                                  fname, &mtimespec);
 
1577
 
 
1578
        if (lck == NULL) {
 
1579
                DEBUG(0, ("onefs_open_directory: Could not get share mode "
 
1580
                          "lock for %s\n", fname));
 
1581
                fd_close(fsp);
 
1582
                file_free(req, fsp);
 
1583
                return NT_STATUS_SHARING_VIOLATION;
 
1584
        }
 
1585
 
 
1586
        if (lck->delete_on_close) {
 
1587
                TALLOC_FREE(lck);
 
1588
                fd_close(fsp);
 
1589
                file_free(req, fsp);
 
1590
                return NT_STATUS_DELETE_PENDING;
 
1591
        }
 
1592
 
 
1593
        set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
 
1594
 
 
1595
        /*
 
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.
 
1598
         */
 
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)) {
 
1603
                        TALLOC_FREE(lck);
 
1604
                        fd_close(fsp);
 
1605
                        file_free(req, fsp);
 
1606
                        return status;
 
1607
                }
 
1608
 
 
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;
 
1613
                }
 
1614
        }
 
1615
 
 
1616
        TALLOC_FREE(lck);
 
1617
 
 
1618
        if (pinfo) {
 
1619
                *pinfo = info;
 
1620
        }
 
1621
 
 
1622
        *result = fsp;
 
1623
        return NT_STATUS_OK;
 
1624
}
 
1625
 
 
1626
/*
 
1627
 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
 
1628
 */
 
1629
static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
 
1630
                                           struct smb_request *req,
 
1631
                                           const char *fname,
 
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,
 
1642
                                           int *pinfo,
 
1643
                                           struct onefs_fsp_data *fsp_data,
 
1644
                                           SMB_STRUCT_STAT *psbuf)
 
1645
{
 
1646
        SMB_STRUCT_STAT sbuf;
 
1647
        int info = FILE_WAS_OPENED;
 
1648
        files_struct *base_fsp = NULL;
 
1649
        files_struct *fsp = NULL;
 
1650
        NTSTATUS status;
 
1651
 
 
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, "
 
1656
                  "fname = %s\n",
 
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));
 
1664
 
 
1665
        if (create_options & FILE_OPEN_BY_FILE_ID) {
 
1666
                status = NT_STATUS_NOT_SUPPORTED;
 
1667
                goto fail;
 
1668
        }
 
1669
 
 
1670
        if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
 
1671
                status = NT_STATUS_INVALID_PARAMETER;
 
1672
                goto fail;
 
1673
        }
 
1674
 
 
1675
        if (req == NULL) {
 
1676
                SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
 
1677
                            NO_OPLOCK);
 
1678
                oplock_request |= INTERNAL_OPEN_ONLY;
 
1679
        }
 
1680
 
 
1681
        if (psbuf != NULL) {
 
1682
                sbuf = *psbuf;
 
1683
        }
 
1684
        else {
 
1685
                if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
 
1686
                        SET_STAT_INVALID(sbuf);
 
1687
                }
 
1688
        }
 
1689
 
 
1690
        if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
 
1691
                PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
 
1692
                access_mask &= ~SYSTEM_SECURITY_ACCESS;
 
1693
        }
 
1694
 
 
1695
        if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
 
1696
            && (access_mask & DELETE_ACCESS)
 
1697
            && !is_ntfs_stream_name(fname)) {
 
1698
                /*
 
1699
                 * We can't open a file with DELETE access if any of the
 
1700
                 * streams is open without FILE_SHARE_DELETE
 
1701
                 */
 
1702
                status = open_streams_for_delete(conn, fname);
 
1703
 
 
1704
                if (!NT_STATUS_IS_OK(status)) {
 
1705
                        goto fail;
 
1706
                }
 
1707
        }
 
1708
 
 
1709
        if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
 
1710
            && is_ntfs_stream_name(fname)) {
 
1711
                char *base;
 
1712
                uint32 base_create_disposition;
 
1713
 
 
1714
                if (create_options & FILE_DIRECTORY_FILE) {
 
1715
                        status = NT_STATUS_NOT_A_DIRECTORY;
 
1716
                        goto fail;
 
1717
                }
 
1718
 
 
1719
                status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
 
1720
                                                      &base, NULL);
 
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)));
 
1725
                        goto fail;
 
1726
                }
 
1727
 
 
1728
                SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
 
1729
 
 
1730
                switch (create_disposition) {
 
1731
                case FILE_OPEN:
 
1732
                        base_create_disposition = FILE_OPEN;
 
1733
                        break;
 
1734
                default:
 
1735
                        base_create_disposition = FILE_OPEN_IF;
 
1736
                        break;
 
1737
                }
 
1738
 
 
1739
                status = onefs_create_file_unixpath(
 
1740
                        conn,                           /* conn */
 
1741
                        NULL,                           /* req */
 
1742
                        base,                           /* fname */
 
1743
                        SYNCHRONIZE_ACCESS,             /* access_mask */
 
1744
                        (FILE_SHARE_READ |
 
1745
                            FILE_SHARE_WRITE |
 
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 */
 
1752
                        NULL,                           /* sd */
 
1753
                        NULL,                           /* ea_list */
 
1754
                        &base_fsp,                      /* result */
 
1755
                        NULL,                           /* pinfo */
 
1756
                        NULL,                           /* fsp_data */
 
1757
                        NULL);                          /* psbuf */
 
1758
 
 
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)));
 
1762
                        goto fail;
 
1763
                }
 
1764
 
 
1765
                /*
 
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).
 
1769
                 */
 
1770
                if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
 
1771
                     NO_OPLOCK) {
 
1772
                        DEBUG(5, ("Oplock(%d) being requested on a stream! "
 
1773
                                  "Ignoring oplock request: fname=%s\n",
 
1774
                                  oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
 
1775
                                  fname));
 
1776
                        /* Request NO_OPLOCK instead. */
 
1777
                        oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
 
1778
                }
 
1779
        }
 
1780
 
 
1781
        /* Covert generic bits in the security descriptor. */
 
1782
        if (sd != NULL) {
 
1783
                security_acl_map_generic(sd->dacl, &file_generic_mapping);
 
1784
                security_acl_map_generic(sd->sacl, &file_generic_mapping);
 
1785
        }
 
1786
 
 
1787
        /*
 
1788
         * If it's a request for a directory open, deal with it separately.
 
1789
         */
 
1790
 
 
1791
        if (create_options & FILE_DIRECTORY_FILE) {
 
1792
 
 
1793
                if (create_options & FILE_NON_DIRECTORY_FILE) {
 
1794
                        status = NT_STATUS_INVALID_PARAMETER;
 
1795
                        goto fail;
 
1796
                }
 
1797
 
 
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;
 
1802
                        goto fail;
 
1803
                }
 
1804
 
 
1805
                /*
 
1806
                 * We will get a create directory here if the Win32
 
1807
                 * app specified a security descriptor in the
 
1808
                 * CreateDirectory() call.
 
1809
                 */
 
1810
 
 
1811
                status = onefs_open_directory(
 
1812
                        conn,                           /* conn */
 
1813
                        req,                            /* req */
 
1814
                        fname,                          /* fname */
 
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 */
 
1820
                        sd,                             /* sd */
 
1821
                        &fsp,                           /* result */
 
1822
                        &info,                          /* pinfo */
 
1823
                        &sbuf);                         /* psbuf */
 
1824
        } else {
 
1825
 
 
1826
                /*
 
1827
                 * Ordinary file case.
 
1828
                 */
 
1829
 
 
1830
                status = file_new(req, conn, &fsp);
 
1831
                if(!NT_STATUS_IS_OK(status)) {
 
1832
                        goto fail;
 
1833
                }
 
1834
 
 
1835
                /*
 
1836
                 * We're opening the stream element of a base_fsp
 
1837
                 * we already opened. Set up the base_fsp pointer.
 
1838
                 */
 
1839
                if (base_fsp) {
 
1840
                        fsp->base_fsp = base_fsp;
 
1841
                }
 
1842
 
 
1843
                status = onefs_open_file_ntcreate(
 
1844
                        conn,                           /* conn */
 
1845
                        req,                            /* req */
 
1846
                        fname,                          /* fname */
 
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 */
 
1853
                        sd,                             /* sd */
 
1854
                        fsp,                            /* result */
 
1855
                        &info,                          /* pinfo */
 
1856
                        fsp_data,                       /* fsp_data */
 
1857
                        &sbuf);                         /* psbuf */
 
1858
 
 
1859
                if(!NT_STATUS_IS_OK(status)) {
 
1860
                        file_free(req, fsp);
 
1861
                        fsp = NULL;
 
1862
                }
 
1863
 
 
1864
                if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
 
1865
 
 
1866
                        /* A stream open never opens a directory */
 
1867
 
 
1868
                        if (base_fsp) {
 
1869
                                status = NT_STATUS_FILE_IS_A_DIRECTORY;
 
1870
                                goto fail;
 
1871
                        }
 
1872
 
 
1873
                        /*
 
1874
                         * Fail the open if it was explicitly a non-directory
 
1875
                         * file.
 
1876
                         */
 
1877
 
 
1878
                        if (create_options & FILE_NON_DIRECTORY_FILE) {
 
1879
                                status = NT_STATUS_FILE_IS_A_DIRECTORY;
 
1880
                                goto fail;
 
1881
                        }
 
1882
 
 
1883
                        create_options |= FILE_DIRECTORY_FILE;
 
1884
 
 
1885
                        status = onefs_open_directory(
 
1886
                                conn,                   /* conn */
 
1887
                                req,                    /* req */
 
1888
                                fname,                  /* fname */
 
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 */
 
1894
                                sd,                     /* sd */
 
1895
                                &fsp,                   /* result */
 
1896
                                &info,                  /* pinfo */
 
1897
                                &sbuf);                 /* psbuf */
 
1898
                }
 
1899
        }
 
1900
 
 
1901
        if (!NT_STATUS_IS_OK(status)) {
 
1902
                goto fail;
 
1903
        }
 
1904
 
 
1905
        fsp->base_fsp = base_fsp;
 
1906
 
 
1907
        SMB_ASSERT(fsp);
 
1908
 
 
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)) {
 
1912
                        goto fail;
 
1913
                }
 
1914
        }
 
1915
 
 
1916
        if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
 
1917
                status = NT_STATUS_ACCESS_DENIED;
 
1918
                goto fail;
 
1919
        }
 
1920
 
 
1921
        /* Save the requested allocation size. */
 
1922
        if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
 
1923
                if (allocation_size
 
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;
 
1930
                                goto fail;
 
1931
                        }
 
1932
                        if (vfs_allocate_file_space(
 
1933
                                    fsp, fsp->initial_allocation_size) == -1) {
 
1934
                                status = NT_STATUS_DISK_FULL;
 
1935
                                goto fail;
 
1936
                        }
 
1937
                } else {
 
1938
                        fsp->initial_allocation_size = smb_roundup(
 
1939
                                fsp->conn, (uint64_t)sbuf.st_size);
 
1940
                }
 
1941
        }
 
1942
 
 
1943
        DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
 
1944
 
 
1945
        *result = fsp;
 
1946
        if (pinfo != NULL) {
 
1947
                *pinfo = info;
 
1948
        }
 
1949
        if (psbuf != NULL) {
 
1950
                if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
 
1951
                        *psbuf = sbuf;
 
1952
                }
 
1953
                else {
 
1954
                        SMB_VFS_FSTAT(fsp, psbuf);
 
1955
                }
 
1956
        }
 
1957
        return NT_STATUS_OK;
 
1958
 
 
1959
 fail:
 
1960
        DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
 
1961
 
 
1962
        if (fsp != NULL) {
 
1963
                if (base_fsp && fsp->base_fsp == base_fsp) {
 
1964
                        /*
 
1965
                         * The close_file below will close
 
1966
                         * fsp->base_fsp.
 
1967
                         */
 
1968
                        base_fsp = NULL;
 
1969
                }
 
1970
                close_file(req, fsp, ERROR_CLOSE);
 
1971
                fsp = NULL;
 
1972
        }
 
1973
        if (base_fsp != NULL) {
 
1974
                close_file(req, base_fsp, ERROR_CLOSE);
 
1975
                base_fsp = NULL;
 
1976
        }
 
1977
        return status;
 
1978
}
 
1979
 
 
1980
static void destroy_onefs_fsp_data(void *p_data)
 
1981
{
 
1982
        struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
 
1983
 
 
1984
        destroy_onefs_callback_record(fsp_data->oplock_callback_id);
 
1985
}
 
1986
 
 
1987
/**
 
1988
 * SMB_VFS_CREATE_FILE interface to onefs.
 
1989
 */
 
1990
NTSTATUS onefs_create_file(vfs_handle_struct *handle,
 
1991
                           struct smb_request *req,
 
1992
                           uint16_t root_dir_fid,
 
1993
                           const char *fname,
 
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,
 
2005
                           int *pinfo,
 
2006
                           SMB_STRUCT_STAT *psbuf)
 
2007
{
 
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;
 
2014
        NTSTATUS status;
 
2015
 
 
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));
 
2030
 
 
2031
        /* Get the file name if root_dir_fid was specified. */
 
2032
        if (root_dir_fid != 0) {
 
2033
                char *new_fname;
 
2034
 
 
2035
                status = get_relative_fid_filename(conn, req, root_dir_fid,
 
2036
                                                   fname, &new_fname);
 
2037
                if (!NT_STATUS_IS_OK(status)) {
 
2038
                        goto fail;
 
2039
                }
 
2040
 
 
2041
                fname = new_fname;
 
2042
        }
 
2043
 
 
2044
        /* Resolve the file name if this was a DFS pathname. */
 
2045
        if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
 
2046
                char *resolved_fname;
 
2047
 
 
2048
                status = resolve_dfspath(talloc_tos(), conn, true, fname,
 
2049
                                         &resolved_fname);
 
2050
 
 
2051
                if (!NT_STATUS_IS_OK(status)) {
 
2052
                        /*
 
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
 
2057
                         */
 
2058
                        goto fail;
 
2059
                }
 
2060
                fname = resolved_fname;
 
2061
        }
 
2062
 
 
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);
 
2066
        }
 
2067
 
 
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;
 
2071
 
 
2072
                SET_STAT_INVALID(sbuf);
 
2073
 
 
2074
                status = unix_convert(talloc_tos(), conn, fname, False,
 
2075
                                      &converted_fname, NULL, &sbuf);
 
2076
                if (!NT_STATUS_IS_OK(status)) {
 
2077
                        goto fail;
 
2078
                }
 
2079
                fname = converted_fname;
 
2080
        } else {
 
2081
                if (psbuf != NULL) {
 
2082
                        sbuf = *psbuf;
 
2083
                } else {
 
2084
                        if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
 
2085
                                SET_STAT_INVALID(sbuf);
 
2086
                        }
 
2087
                }
 
2088
 
 
2089
        }
 
2090
 
 
2091
        TALLOC_FREE(case_state);
 
2092
 
 
2093
        /* All file access must go through check_name() */
 
2094
        status = check_name(conn, fname);
 
2095
        if (!NT_STATUS_IS_OK(status)) {
 
2096
                goto fail;
 
2097
        }
 
2098
 
 
2099
        status = onefs_create_file_unixpath(
 
2100
                conn,                                   /* conn */
 
2101
                req,                                    /* req */
 
2102
                fname,                                  /* fname */
 
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 */
 
2110
                sd,                                     /* sd */
 
2111
                ea_list,                                /* ea_list */
 
2112
                &fsp,                                   /* result */
 
2113
                &info,                                  /* pinfo */
 
2114
                &fsp_data,                              /* fsp_data */
 
2115
                &sbuf);                                 /* psbuf */
 
2116
 
 
2117
        if (!NT_STATUS_IS_OK(status)) {
 
2118
                goto fail;
 
2119
        }
 
2120
 
 
2121
        DEBUG(10, ("onefs_create_file: info=%d\n", info));
 
2122
 
 
2123
        /*
 
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.
 
2128
         */
 
2129
        if (fsp) {
 
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);
 
2134
 
 
2135
                if (fsp_data_tmp == NULL) {
 
2136
                        status = NT_STATUS_NO_MEMORY;
 
2137
                        goto fail;
 
2138
                }
 
2139
 
 
2140
                *fsp_data_tmp = fsp_data;
 
2141
        }
 
2142
 
 
2143
        *result = fsp;
 
2144
        if (pinfo != NULL) {
 
2145
                *pinfo = info;
 
2146
        }
 
2147
        if (psbuf != NULL) {
 
2148
                *psbuf = sbuf;
 
2149
        }
 
2150
        return NT_STATUS_OK;
 
2151
 
 
2152
 fail:
 
2153
        DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
 
2154
 
 
2155
        if (fsp != NULL) {
 
2156
                close_file(req, fsp, ERROR_CLOSE);
 
2157
                fsp = NULL;
 
2158
        }
 
2159
        return status;
 
2160
}