~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/locking/locking.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Unix SMB/CIFS implementation.
3
 
   Locking functions
4
 
   Copyright (C) Andrew Tridgell 1992-2000
5
 
   Copyright (C) Jeremy Allison 1992-2006
6
 
   Copyright (C) Volker Lendecke 2005
7
 
   
8
 
   This program is free software; you can redistribute it and/or modify
9
 
   it under the terms of the GNU General Public License as published by
10
 
   the Free Software Foundation; either version 2 of the License, or
11
 
   (at your option) any later version.
12
 
   
13
 
   This program is distributed in the hope that it will be useful,
14
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
   GNU General Public License for more details.
17
 
   
18
 
   You should have received a copy of the GNU General Public License
19
 
   along with this program; if not, write to the Free Software
20
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 
 
22
 
   Revision History:
23
 
 
24
 
   12 aug 96: Erik.Devriendt@te6.siemens.be
25
 
   added support for shared memory implementation of share mode locking
26
 
 
27
 
   May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
28
 
   locking to deal with multiple share modes per open file.
29
 
 
30
 
   September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
31
 
   support.
32
 
 
33
 
   rewrtten completely to use new tdb code. Tridge, Dec '99
34
 
 
35
 
   Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
36
 
   Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
37
 
*/
38
 
 
39
 
#include "includes.h"
40
 
 
41
 
#undef DBGC_CLASS
42
 
#define DBGC_CLASS DBGC_LOCKING
43
 
 
44
 
/* the locking database handle */
45
 
static TDB_CONTEXT *tdb;
46
 
 
47
 
/****************************************************************************
48
 
 Debugging aids :-).
49
 
****************************************************************************/
50
 
 
51
 
const char *lock_type_name(enum brl_type lock_type)
52
 
{
53
 
        switch (lock_type) {
54
 
                case READ_LOCK:
55
 
                        return "READ";
56
 
                case WRITE_LOCK:
57
 
                        return "WRITE";
58
 
                case PENDING_LOCK:
59
 
                        return "PENDING";
60
 
                default:
61
 
                        return "other";
62
 
        }
63
 
}
64
 
 
65
 
const char *lock_flav_name(enum brl_flavour lock_flav)
66
 
{
67
 
        return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
68
 
}
69
 
 
70
 
/****************************************************************************
71
 
 Utility function called to see if a file region is locked.
72
 
 Called in the read/write codepath.
73
 
****************************************************************************/
74
 
 
75
 
BOOL is_locked(files_struct *fsp,
76
 
                uint32 smbpid,
77
 
                SMB_BIG_UINT count,
78
 
                SMB_BIG_UINT offset, 
79
 
                enum brl_type lock_type)
80
 
{
81
 
        int snum = SNUM(fsp->conn);
82
 
        int strict_locking = lp_strict_locking(snum);
83
 
        enum brl_flavour lock_flav = lp_posix_cifsu_locktype();
84
 
        BOOL ret = True;
85
 
        
86
 
        if (count == 0) {
87
 
                return False;
88
 
        }
89
 
 
90
 
        if (!lp_locking(snum) || !strict_locking) {
91
 
                return False;
92
 
        }
93
 
 
94
 
        if (strict_locking == Auto) {
95
 
                if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
96
 
                        DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
97
 
                        ret = False;
98
 
                } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
99
 
                           (lock_type == READ_LOCK)) {
100
 
                        DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
101
 
                        ret = False;
102
 
                } else {
103
 
                        struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
104
 
                        if (!br_lck) {
105
 
                                return False;
106
 
                        }
107
 
                        ret = !brl_locktest(br_lck,
108
 
                                        smbpid,
109
 
                                        procid_self(),
110
 
                                        offset,
111
 
                                        count,
112
 
                                        lock_type,
113
 
                                        lock_flav);
114
 
                        TALLOC_FREE(br_lck);
115
 
                }
116
 
        } else {
117
 
                struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
118
 
                if (!br_lck) {
119
 
                        return False;
120
 
                }
121
 
                ret = !brl_locktest(br_lck,
122
 
                                smbpid,
123
 
                                procid_self(),
124
 
                                offset,
125
 
                                count,
126
 
                                lock_type,
127
 
                                lock_flav);
128
 
                TALLOC_FREE(br_lck);
129
 
        }
130
 
 
131
 
        DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
132
 
                        lock_flav_name(lock_flav),
133
 
                        (double)offset, (double)count, ret ? "locked" : "unlocked",
134
 
                        fsp->fnum, fsp->fsp_name ));
135
 
 
136
 
        return ret;
137
 
}
138
 
 
139
 
/****************************************************************************
140
 
 Find out if a lock could be granted - return who is blocking us if we can't.
141
 
****************************************************************************/
142
 
 
143
 
NTSTATUS query_lock(files_struct *fsp,
144
 
                        uint32 *psmbpid,
145
 
                        SMB_BIG_UINT *pcount,
146
 
                        SMB_BIG_UINT *poffset,
147
 
                        enum brl_type *plock_type,
148
 
                        enum brl_flavour lock_flav)
149
 
{
150
 
        struct byte_range_lock *br_lck = NULL;
151
 
        NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
152
 
 
153
 
        if (!fsp->can_lock) {
154
 
                return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
155
 
        }
156
 
 
157
 
        if (!lp_locking(SNUM(fsp->conn))) {
158
 
                return NT_STATUS_OK;
159
 
        }
160
 
 
161
 
        br_lck = brl_get_locks(NULL, fsp);
162
 
        if (!br_lck) {
163
 
                return NT_STATUS_NO_MEMORY;
164
 
        }
165
 
 
166
 
        status = brl_lockquery(br_lck,
167
 
                        psmbpid,
168
 
                        procid_self(),
169
 
                        poffset,
170
 
                        pcount,
171
 
                        plock_type,
172
 
                        lock_flav);
173
 
 
174
 
        TALLOC_FREE(br_lck);
175
 
        return status;
176
 
}
177
 
 
178
 
/****************************************************************************
179
 
 Utility function called by locking requests.
180
 
****************************************************************************/
181
 
 
182
 
NTSTATUS do_lock(files_struct *fsp,
183
 
                        uint32 lock_pid,
184
 
                        SMB_BIG_UINT count,
185
 
                        SMB_BIG_UINT offset,
186
 
                        enum brl_type lock_type,
187
 
                        enum brl_flavour lock_flav,
188
 
                        BOOL *my_lock_ctx)
189
 
{
190
 
        struct byte_range_lock *br_lck = NULL;
191
 
        NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
192
 
 
193
 
        if (!fsp->can_lock) {
194
 
                return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
195
 
        }
196
 
 
197
 
        if (!lp_locking(SNUM(fsp->conn))) {
198
 
                return NT_STATUS_OK;
199
 
        }
200
 
 
201
 
        /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
202
 
 
203
 
        DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
204
 
                lock_flav_name(lock_flav), lock_type_name(lock_type),
205
 
                (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
206
 
 
207
 
        br_lck = brl_get_locks(NULL, fsp);
208
 
        if (!br_lck) {
209
 
                return NT_STATUS_NO_MEMORY;
210
 
        }
211
 
 
212
 
        status = brl_lock(br_lck,
213
 
                        lock_pid,
214
 
                        procid_self(),
215
 
                        offset,
216
 
                        count, 
217
 
                        lock_type,
218
 
                        lock_flav,
219
 
                        my_lock_ctx);
220
 
 
221
 
        TALLOC_FREE(br_lck);
222
 
        return status;
223
 
}
224
 
 
225
 
/****************************************************************************
226
 
 Utility function called by locking requests. This is *DISGUSTING*. It also
227
 
 appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
228
 
 is so slow on the locking tests...... ? This is the reason. Much though I hate
229
 
 it, we need this. JRA.
230
 
****************************************************************************/
231
 
 
232
 
NTSTATUS do_lock_spin(files_struct *fsp,
233
 
                        uint32 lock_pid,
234
 
                        SMB_BIG_UINT count,
235
 
                        SMB_BIG_UINT offset,
236
 
                        enum brl_type lock_type,
237
 
                        enum brl_flavour lock_flav,
238
 
                        BOOL *my_lock_ctx)
239
 
{
240
 
        int j, maxj = lp_lock_spin_count();
241
 
        int sleeptime = lp_lock_sleep_time();
242
 
        NTSTATUS status, ret;
243
 
 
244
 
        if (maxj <= 0) {
245
 
                maxj = 1;
246
 
        }
247
 
 
248
 
        ret = NT_STATUS_OK; /* to keep dumb compilers happy */
249
 
 
250
 
        for (j = 0; j < maxj; j++) {
251
 
                status = do_lock(fsp,
252
 
                                lock_pid,
253
 
                                count,
254
 
                                offset,
255
 
                                lock_type,
256
 
                                lock_flav,
257
 
                                my_lock_ctx);
258
 
 
259
 
                if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
260
 
                    !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
261
 
                        return status;
262
 
                }
263
 
                /* if we do fail then return the first error code we got */
264
 
                if (j == 0) {
265
 
                        ret = status;
266
 
                        /* Don't spin if we blocked ourselves. */
267
 
                        if (*my_lock_ctx) {
268
 
                                return ret;
269
 
                        }
270
 
 
271
 
                        /* Only spin for Windows locks. */
272
 
                        if (lock_flav == POSIX_LOCK) {
273
 
                                return ret;
274
 
                        }
275
 
                }
276
 
 
277
 
                if (sleeptime) {
278
 
                        sys_usleep(sleeptime);
279
 
                }
280
 
        }
281
 
        return ret;
282
 
}
283
 
 
284
 
/****************************************************************************
285
 
 Utility function called by unlocking requests.
286
 
****************************************************************************/
287
 
 
288
 
NTSTATUS do_unlock(files_struct *fsp,
289
 
                        uint32 lock_pid,
290
 
                        SMB_BIG_UINT count,
291
 
                        SMB_BIG_UINT offset,
292
 
                        enum brl_flavour lock_flav)
293
 
{
294
 
        BOOL ok = False;
295
 
        struct byte_range_lock *br_lck = NULL;
296
 
        
297
 
        if (!fsp->can_lock) {
298
 
                return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
299
 
        }
300
 
        
301
 
        if (!lp_locking(SNUM(fsp->conn))) {
302
 
                return NT_STATUS_OK;
303
 
        }
304
 
        
305
 
        DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
306
 
                  (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
307
 
 
308
 
        br_lck = brl_get_locks(NULL, fsp);
309
 
        if (!br_lck) {
310
 
                return NT_STATUS_NO_MEMORY;
311
 
        }
312
 
 
313
 
        ok = brl_unlock(br_lck,
314
 
                        lock_pid,
315
 
                        procid_self(),
316
 
                        offset,
317
 
                        count,
318
 
                        lock_flav);
319
 
   
320
 
        TALLOC_FREE(br_lck);
321
 
 
322
 
        if (!ok) {
323
 
                DEBUG(10,("do_unlock: returning ERRlock.\n" ));
324
 
                return NT_STATUS_RANGE_NOT_LOCKED;
325
 
        }
326
 
 
327
 
        return NT_STATUS_OK;
328
 
}
329
 
 
330
 
/****************************************************************************
331
 
 Remove any locks on this fd. Called from file_close().
332
 
****************************************************************************/
333
 
 
334
 
void locking_close_file(files_struct *fsp)
335
 
{
336
 
        struct byte_range_lock *br_lck;
337
 
 
338
 
        if (!lp_locking(SNUM(fsp->conn))) {
339
 
                return;
340
 
        }
341
 
 
342
 
        br_lck = brl_get_locks(NULL,fsp);
343
 
        if (br_lck) {
344
 
                brl_close_fnum(br_lck);
345
 
                TALLOC_FREE(br_lck);
346
 
        }
347
 
}
348
 
 
349
 
/****************************************************************************
350
 
 Initialise the locking functions.
351
 
****************************************************************************/
352
 
 
353
 
static int open_read_only;
354
 
 
355
 
BOOL locking_init(int read_only)
356
 
{
357
 
        brl_init(read_only);
358
 
 
359
 
        if (tdb)
360
 
                return True;
361
 
 
362
 
        tdb = tdb_open_log(lock_path("locking.tdb"), 
363
 
                        lp_open_files_db_hash_size(),
364
 
                        TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), 
365
 
                        read_only?O_RDONLY:O_RDWR|O_CREAT,
366
 
                        0644);
367
 
 
368
 
        if (!tdb) {
369
 
                DEBUG(0,("ERROR: Failed to initialise locking database\n"));
370
 
                return False;
371
 
        }
372
 
 
373
 
        if (!posix_locking_init(read_only))
374
 
                return False;
375
 
 
376
 
        open_read_only = read_only;
377
 
 
378
 
        return True;
379
 
}
380
 
 
381
 
/*******************************************************************
382
 
 Deinitialize the share_mode management.
383
 
******************************************************************/
384
 
 
385
 
BOOL locking_end(void)
386
 
{
387
 
        BOOL ret = True;
388
 
 
389
 
        brl_shutdown(open_read_only);
390
 
        if (tdb) {
391
 
                if (tdb_close(tdb) != 0)
392
 
                        ret = False;
393
 
        }
394
 
 
395
 
        return ret;
396
 
}
397
 
 
398
 
/*******************************************************************
399
 
 Form a static locking key for a dev/inode pair.
400
 
******************************************************************/
401
 
 
402
 
/* key and data records in the tdb locking database */
403
 
struct locking_key {
404
 
        SMB_DEV_T dev;
405
 
        SMB_INO_T ino;
406
 
};
407
 
 
408
 
/*******************************************************************
409
 
 Form a static locking key for a dev/inode pair.
410
 
******************************************************************/
411
 
 
412
 
static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
413
 
{
414
 
        static struct locking_key key;
415
 
        TDB_DATA kbuf;
416
 
 
417
 
        memset(&key, '\0', sizeof(key));
418
 
        key.dev = dev;
419
 
        key.ino = inode;
420
 
        kbuf.dptr = (char *)&key;
421
 
        kbuf.dsize = sizeof(key);
422
 
        return kbuf;
423
 
}
424
 
 
425
 
/*******************************************************************
426
 
 Print out a share mode.
427
 
********************************************************************/
428
 
 
429
 
char *share_mode_str(int num, struct share_mode_entry *e)
430
 
{
431
 
        static pstring share_str;
432
 
 
433
 
        slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s "
434
 
                 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
435
 
                 "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, "
436
 
                 "uid = %u, dev = 0x%x, inode = %.0f",
437
 
                 num,
438
 
                 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
439
 
                 procid_str_static(&e->pid),
440
 
                 e->share_access, e->private_options,
441
 
                 e->access_mask, e->op_mid, e->op_type, e->share_file_id,
442
 
                 (unsigned int)e->uid, (unsigned int)e->dev, (double)e->inode );
443
 
 
444
 
        return share_str;
445
 
}
446
 
 
447
 
/*******************************************************************
448
 
 Print out a share mode table.
449
 
********************************************************************/
450
 
 
451
 
static void print_share_mode_table(struct locking_data *data)
452
 
{
453
 
        int num_share_modes = data->u.s.num_share_mode_entries;
454
 
        struct share_mode_entry *shares =
455
 
                (struct share_mode_entry *)(data + 1);
456
 
        int i;
457
 
 
458
 
        for (i = 0; i < num_share_modes; i++) {
459
 
                struct share_mode_entry entry;
460
 
 
461
 
                memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
462
 
                DEBUG(10,("print_share_mode_table: %s\n",
463
 
                          share_mode_str(i, &entry)));
464
 
        }
465
 
}
466
 
 
467
 
/*******************************************************************
468
 
 Get all share mode entries for a dev/inode pair.
469
 
********************************************************************/
470
 
 
471
 
static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
472
 
{
473
 
        struct locking_data *data;
474
 
        int i;
475
 
 
476
 
        if (dbuf.dsize < sizeof(struct locking_data)) {
477
 
                smb_panic("PANIC: parse_share_modes: buffer too short.\n");
478
 
        }
479
 
 
480
 
        data = (struct locking_data *)dbuf.dptr;
481
 
 
482
 
        lck->delete_on_close = data->u.s.delete_on_close;
483
 
        lck->initial_delete_on_close = data->u.s.initial_delete_on_close;
484
 
        lck->num_share_modes = data->u.s.num_share_mode_entries;
485
 
 
486
 
        DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
487
 
                   "initial_delete_on_close: %d, "
488
 
                   "num_share_modes: %d\n",
489
 
                lck->delete_on_close,
490
 
                lck->initial_delete_on_close,
491
 
                lck->num_share_modes));
492
 
 
493
 
        if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
494
 
                DEBUG(0, ("invalid number of share modes: %d\n",
495
 
                          lck->num_share_modes));
496
 
                smb_panic("PANIC: invalid number of share modes");
497
 
        }
498
 
 
499
 
        lck->share_modes = NULL;
500
 
        
501
 
        if (lck->num_share_modes != 0) {
502
 
 
503
 
                if (dbuf.dsize < (sizeof(struct locking_data) +
504
 
                                  (lck->num_share_modes *
505
 
                                   sizeof(struct share_mode_entry)))) {
506
 
                        smb_panic("PANIC: parse_share_modes: buffer too short.\n");
507
 
                }
508
 
                                  
509
 
                lck->share_modes = (struct share_mode_entry *)
510
 
                        talloc_memdup(lck, dbuf.dptr+sizeof(*data),
511
 
                                      lck->num_share_modes *
512
 
                                      sizeof(struct share_mode_entry));
513
 
 
514
 
                if (lck->share_modes == NULL) {
515
 
                        smb_panic("talloc failed\n");
516
 
                }
517
 
        }
518
 
 
519
 
        /* Get any delete token. */
520
 
        if (data->u.s.delete_token_size) {
521
 
                char *p = dbuf.dptr + sizeof(*data) +
522
 
                                (lck->num_share_modes *
523
 
                                sizeof(struct share_mode_entry));
524
 
 
525
 
                if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
526
 
                                ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
527
 
                        DEBUG(0, ("parse_share_modes: invalid token size %d\n",
528
 
                                data->u.s.delete_token_size));
529
 
                        smb_panic("parse_share_modes: invalid token size\n");
530
 
                }
531
 
 
532
 
                lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
533
 
                if (!lck->delete_token) {
534
 
                        smb_panic("talloc failed\n");
535
 
                }
536
 
 
537
 
                /* Copy out the uid and gid. */
538
 
                memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
539
 
                p += sizeof(uid_t);
540
 
                memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
541
 
                p += sizeof(gid_t);
542
 
 
543
 
                /* Any supplementary groups ? */
544
 
                lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
545
 
                                        ((data->u.s.delete_token_size -
546
 
                                                (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
547
 
 
548
 
                if (lck->delete_token->ngroups) {
549
 
                        /* Make this a talloc child of lck->delete_token. */
550
 
                        lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
551
 
                                                        lck->delete_token->ngroups);
552
 
                        if (!lck->delete_token) {
553
 
                                smb_panic("talloc failed\n");
554
 
                        }
555
 
 
556
 
                        for (i = 0; i < lck->delete_token->ngroups; i++) {
557
 
                                memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
558
 
                                p += sizeof(gid_t);
559
 
                        }
560
 
                }
561
 
 
562
 
        } else {
563
 
                lck->delete_token = NULL;
564
 
        }
565
 
 
566
 
        /* Save off the associated service path and filename. */
567
 
        lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
568
 
                                        (lck->num_share_modes *
569
 
                                        sizeof(struct share_mode_entry)) +
570
 
                                        data->u.s.delete_token_size );
571
 
 
572
 
        lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
573
 
                                        (lck->num_share_modes *
574
 
                                        sizeof(struct share_mode_entry)) +
575
 
                                        data->u.s.delete_token_size +
576
 
                                        strlen(lck->servicepath) + 1 );
577
 
 
578
 
        /*
579
 
         * Ensure that each entry has a real process attached.
580
 
         */
581
 
 
582
 
        for (i = 0; i < lck->num_share_modes; i++) {
583
 
                struct share_mode_entry *entry_p = &lck->share_modes[i];
584
 
                DEBUG(10,("parse_share_modes: %s\n",
585
 
                          share_mode_str(i, entry_p) ));
586
 
                if (!process_exists(entry_p->pid)) {
587
 
                        DEBUG(10,("parse_share_modes: deleted %s\n",
588
 
                                  share_mode_str(i, entry_p) ));
589
 
                        entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
590
 
                        lck->modified = True;
591
 
                }
592
 
        }
593
 
 
594
 
        return True;
595
 
}
596
 
 
597
 
static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
598
 
{
599
 
        TDB_DATA result;
600
 
        int num_valid = 0;
601
 
        int i;
602
 
        struct locking_data *data;
603
 
        ssize_t offset;
604
 
        ssize_t sp_len;
605
 
        uint32 delete_token_size;
606
 
 
607
 
        result.dptr = NULL;
608
 
        result.dsize = 0;
609
 
 
610
 
        for (i=0; i<lck->num_share_modes; i++) {
611
 
                if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
612
 
                        num_valid += 1;
613
 
                }
614
 
        }
615
 
 
616
 
        if (num_valid == 0) {
617
 
                return result;
618
 
        }
619
 
 
620
 
        sp_len = strlen(lck->servicepath);
621
 
        delete_token_size = (lck->delete_token ?
622
 
                        (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
623
 
 
624
 
        result.dsize = sizeof(*data) +
625
 
                lck->num_share_modes * sizeof(struct share_mode_entry) +
626
 
                delete_token_size +
627
 
                sp_len + 1 +
628
 
                strlen(lck->filename) + 1;
629
 
        result.dptr = TALLOC_ARRAY(lck, char, result.dsize);
630
 
 
631
 
        if (result.dptr == NULL) {
632
 
                smb_panic("talloc failed\n");
633
 
        }
634
 
 
635
 
        data = (struct locking_data *)result.dptr;
636
 
        ZERO_STRUCTP(data);
637
 
        data->u.s.num_share_mode_entries = lck->num_share_modes;
638
 
        data->u.s.delete_on_close = lck->delete_on_close;
639
 
        data->u.s.initial_delete_on_close = lck->initial_delete_on_close;
640
 
        data->u.s.delete_token_size = delete_token_size;
641
 
        DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, tok = %u, num: %d\n",
642
 
                data->u.s.delete_on_close,
643
 
                data->u.s.initial_delete_on_close,
644
 
                (unsigned int)data->u.s.delete_token_size,
645
 
                data->u.s.num_share_mode_entries));
646
 
        memcpy(result.dptr + sizeof(*data), lck->share_modes,
647
 
               sizeof(struct share_mode_entry)*lck->num_share_modes);
648
 
        offset = sizeof(*data) +
649
 
                sizeof(struct share_mode_entry)*lck->num_share_modes;
650
 
 
651
 
        /* Store any delete on close token. */
652
 
        if (lck->delete_token) {
653
 
                char *p = result.dptr + offset;
654
 
 
655
 
                memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
656
 
                p += sizeof(uid_t);
657
 
 
658
 
                memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
659
 
                p += sizeof(gid_t);
660
 
 
661
 
                for (i = 0; i < lck->delete_token->ngroups; i++) {
662
 
                        memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
663
 
                        p += sizeof(gid_t);
664
 
                }
665
 
                offset = p - result.dptr;
666
 
        }
667
 
 
668
 
        safe_strcpy(result.dptr + offset, lck->servicepath,
669
 
                    result.dsize - offset - 1);
670
 
        offset += sp_len + 1;
671
 
        safe_strcpy(result.dptr + offset, lck->filename,
672
 
                    result.dsize - offset - 1);
673
 
 
674
 
        if (DEBUGLEVEL >= 10) {
675
 
                print_share_mode_table(data);
676
 
        }
677
 
 
678
 
        return result;
679
 
}
680
 
 
681
 
static int share_mode_lock_destructor(void *p)
682
 
{
683
 
        struct share_mode_lock *lck =
684
 
                talloc_get_type_abort(p, struct share_mode_lock);
685
 
        TDB_DATA key = locking_key(lck->dev, lck->ino);
686
 
        TDB_DATA data;
687
 
 
688
 
        if (!lck->modified) {
689
 
                goto done;
690
 
        }
691
 
 
692
 
        data = unparse_share_modes(lck);
693
 
 
694
 
        if (data.dptr == NULL) {
695
 
                if (!lck->fresh) {
696
 
                        /* There has been an entry before, delete it */
697
 
                        if (tdb_delete(tdb, key) == -1) {
698
 
                                smb_panic("Could not delete share entry\n");
699
 
                        }
700
 
                }
701
 
                goto done;
702
 
        }
703
 
 
704
 
        if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
705
 
                smb_panic("Could not store share mode entry\n");
706
 
        }
707
 
 
708
 
 done:
709
 
        tdb_chainunlock(tdb, key);
710
 
 
711
 
        return 0;
712
 
}
713
 
 
714
 
struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
715
 
                                                SMB_DEV_T dev, SMB_INO_T ino,
716
 
                                                const char *servicepath,
717
 
                                                const char *fname)
718
 
{
719
 
        struct share_mode_lock *lck;
720
 
        TDB_DATA key = locking_key(dev, ino);
721
 
        TDB_DATA data;
722
 
 
723
 
        lck = TALLOC_P(mem_ctx, struct share_mode_lock);
724
 
        if (lck == NULL) {
725
 
                DEBUG(0, ("talloc failed\n"));
726
 
                return NULL;
727
 
        }
728
 
 
729
 
        /* Ensure we set every field here as the destructor must be
730
 
           valid even if parse_share_modes fails. */
731
 
 
732
 
        lck->servicepath = NULL;
733
 
        lck->filename = NULL;
734
 
        lck->dev = dev;
735
 
        lck->ino = ino;
736
 
        lck->num_share_modes = 0;
737
 
        lck->share_modes = NULL;
738
 
        lck->delete_token = NULL;
739
 
        lck->delete_on_close = False;
740
 
        lck->initial_delete_on_close = False;
741
 
        lck->fresh = False;
742
 
        lck->modified = False;
743
 
 
744
 
        if (tdb_chainlock(tdb, key) != 0) {
745
 
                DEBUG(3, ("Could not lock share entry\n"));
746
 
                TALLOC_FREE(lck);
747
 
                return NULL;
748
 
        }
749
 
 
750
 
        /* We must set the destructor immediately after the chainlock
751
 
           ensure the lock is cleaned up on any of the error return
752
 
           paths below. */
753
 
 
754
 
        talloc_set_destructor(lck, share_mode_lock_destructor);
755
 
 
756
 
        data = tdb_fetch(tdb, key);
757
 
        lck->fresh = (data.dptr == NULL);
758
 
 
759
 
        if (lck->fresh) {
760
 
 
761
 
                if (fname == NULL || servicepath == NULL) {
762
 
                        TALLOC_FREE(lck);
763
 
                        return NULL;
764
 
                }
765
 
                lck->filename = talloc_strdup(lck, fname);
766
 
                lck->servicepath = talloc_strdup(lck, servicepath);
767
 
                if (lck->filename == NULL || lck->servicepath == NULL) {
768
 
                        DEBUG(0, ("talloc failed\n"));
769
 
                        TALLOC_FREE(lck);
770
 
                        return NULL;
771
 
                }
772
 
        } else {
773
 
                if (!parse_share_modes(data, lck)) {
774
 
                        DEBUG(0, ("Could not parse share modes\n"));
775
 
                        TALLOC_FREE(lck);
776
 
                        SAFE_FREE(data.dptr);
777
 
                        return NULL;
778
 
                }
779
 
        }
780
 
 
781
 
        SAFE_FREE(data.dptr);
782
 
 
783
 
        return lck;
784
 
}
785
 
 
786
 
/*******************************************************************
787
 
 Sets the service name and filename for rename.
788
 
 At this point we emit "file renamed" messages to all
789
 
 process id's that have this file open.
790
 
 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
791
 
********************************************************************/
792
 
 
793
 
BOOL rename_share_filename(struct share_mode_lock *lck,
794
 
                        const char *servicepath,
795
 
                        const char *newname)
796
 
{
797
 
        size_t sp_len;
798
 
        size_t fn_len;
799
 
        size_t msg_len;
800
 
        char *frm = NULL;
801
 
        int i;
802
 
 
803
 
        if (!lck) {
804
 
                return False;
805
 
        }
806
 
 
807
 
        DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
808
 
                servicepath, newname));
809
 
 
810
 
        /*
811
 
         * rename_internal_fsp() and rename_internals() add './' to
812
 
         * head of newname if newname does not contain a '/'.
813
 
         */
814
 
        while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
815
 
                newname += 2;
816
 
        }
817
 
 
818
 
        lck->servicepath = talloc_strdup(lck, servicepath);
819
 
        lck->filename = talloc_strdup(lck, newname);
820
 
        if (lck->filename == NULL || lck->servicepath == NULL) {
821
 
                DEBUG(0, ("rename_share_filename: talloc failed\n"));
822
 
                return False;
823
 
        }
824
 
        lck->modified = True;
825
 
 
826
 
        sp_len = strlen(lck->servicepath);
827
 
        fn_len = strlen(lck->filename);
828
 
 
829
 
        msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
830
 
 
831
 
        /* Set up the name changed message. */
832
 
        frm = TALLOC_ARRAY(lck, char, msg_len);
833
 
        if (!frm) {
834
 
                return False;
835
 
        }
836
 
 
837
 
        SDEV_T_VAL(frm,0,lck->dev);
838
 
        SINO_T_VAL(frm,8,lck->ino);
839
 
 
840
 
        DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
841
 
 
842
 
        safe_strcpy(&frm[16], lck->servicepath, sp_len);
843
 
        safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
844
 
 
845
 
        /* Send the messages. */
846
 
        for (i=0; i<lck->num_share_modes; i++) {
847
 
                struct share_mode_entry *se = &lck->share_modes[i];
848
 
                if (!is_valid_share_mode_entry(se)) {
849
 
                        continue;
850
 
                }
851
 
                /* But not to ourselves... */
852
 
                if (procid_is_me(&se->pid)) {
853
 
                        continue;
854
 
                }
855
 
 
856
 
                DEBUG(10,("rename_share_filename: sending rename message to pid %s "
857
 
                        "dev %x, inode  %.0f sharepath %s newname %s\n",
858
 
                        procid_str_static(&se->pid),
859
 
                        (unsigned int)lck->dev, (double)lck->ino,
860
 
                        lck->servicepath, lck->filename ));
861
 
 
862
 
                become_root();
863
 
                message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
864
 
                                frm, msg_len, True);
865
 
                unbecome_root();
866
 
        }
867
 
 
868
 
        return True;
869
 
}
870
 
 
871
 
BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
872
 
{
873
 
        BOOL result;
874
 
        struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, NULL, NULL);
875
 
        if (!lck) {
876
 
                return False;
877
 
        }
878
 
        result = lck->delete_on_close;
879
 
        TALLOC_FREE(lck);
880
 
        return result;
881
 
}
882
 
 
883
 
BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
884
 
{
885
 
        int num_props = 0;
886
 
 
887
 
        num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
888
 
        num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
889
 
        num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
890
 
 
891
 
        SMB_ASSERT(num_props <= 1);
892
 
        return (num_props != 0);
893
 
}
894
 
 
895
 
BOOL is_deferred_open_entry(const struct share_mode_entry *e)
896
 
{
897
 
        return (e->op_type == DEFERRED_OPEN_ENTRY);
898
 
}
899
 
 
900
 
BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
901
 
{
902
 
        return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
903
 
}
904
 
 
905
 
/*******************************************************************
906
 
 Fill a share mode entry.
907
 
********************************************************************/
908
 
 
909
 
static void fill_share_mode_entry(struct share_mode_entry *e,
910
 
                                  files_struct *fsp,
911
 
                                  uid_t uid, uint16 mid, uint16 op_type)
912
 
{
913
 
        ZERO_STRUCTP(e);
914
 
        e->pid = procid_self();
915
 
        e->share_access = fsp->share_access;
916
 
        e->private_options = fsp->fh->private_options;
917
 
        e->access_mask = fsp->access_mask;
918
 
        e->op_mid = mid;
919
 
        e->op_type = op_type;
920
 
        e->time.tv_sec = fsp->open_time.tv_sec;
921
 
        e->time.tv_usec = fsp->open_time.tv_usec;
922
 
        e->dev = fsp->dev;
923
 
        e->inode = fsp->inode;
924
 
        e->share_file_id = fsp->fh->file_id;
925
 
        e->uid = (uint32)uid;
926
 
}
927
 
 
928
 
static void fill_deferred_open_entry(struct share_mode_entry *e,
929
 
                                     const struct timeval request_time,
930
 
                                     SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
931
 
{
932
 
        ZERO_STRUCTP(e);
933
 
        e->pid = procid_self();
934
 
        e->op_mid = mid;
935
 
        e->op_type = DEFERRED_OPEN_ENTRY;
936
 
        e->time.tv_sec = request_time.tv_sec;
937
 
        e->time.tv_usec = request_time.tv_usec;
938
 
        e->dev = dev;
939
 
        e->inode = ino;
940
 
        e->uid = (uint32)-1;
941
 
}
942
 
 
943
 
static void add_share_mode_entry(struct share_mode_lock *lck,
944
 
                                 const struct share_mode_entry *entry)
945
 
{
946
 
        int i;
947
 
 
948
 
        for (i=0; i<lck->num_share_modes; i++) {
949
 
                struct share_mode_entry *e = &lck->share_modes[i];
950
 
                if (is_unused_share_mode_entry(e)) {
951
 
                        *e = *entry;
952
 
                        break;
953
 
                }
954
 
        }
955
 
 
956
 
        if (i == lck->num_share_modes) {
957
 
                /* No unused entry found */
958
 
                ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
959
 
                             &lck->share_modes, &lck->num_share_modes);
960
 
        }
961
 
        lck->modified = True;
962
 
}
963
 
 
964
 
void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
965
 
                        uid_t uid, uint16 mid, uint16 op_type)
966
 
{
967
 
        struct share_mode_entry entry;
968
 
        fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
969
 
        add_share_mode_entry(lck, &entry);
970
 
}
971
 
 
972
 
void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
973
 
                       struct timeval request_time,
974
 
                       SMB_DEV_T dev, SMB_INO_T ino)
975
 
{
976
 
        struct share_mode_entry entry;
977
 
        fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
978
 
        add_share_mode_entry(lck, &entry);
979
 
}
980
 
 
981
 
/*******************************************************************
982
 
 Check if two share mode entries are identical, ignoring oplock 
983
 
 and mid info and desired_access. (Removed paranoia test - it's
984
 
 not automatically a logic error if they are identical. JRA.)
985
 
********************************************************************/
986
 
 
987
 
static BOOL share_modes_identical(struct share_mode_entry *e1,
988
 
                                  struct share_mode_entry *e2)
989
 
{
990
 
        /* We used to check for e1->share_access == e2->share_access here
991
 
           as well as the other fields but 2 different DOS or FCB opens
992
 
           sharing the same share mode entry may validly differ in
993
 
           fsp->share_access field. */
994
 
 
995
 
        return (procid_equal(&e1->pid, &e2->pid) &&
996
 
                e1->dev == e2->dev &&
997
 
                e1->inode == e2->inode &&
998
 
                e1->share_file_id == e2->share_file_id );
999
 
}
1000
 
 
1001
 
static BOOL deferred_open_identical(struct share_mode_entry *e1,
1002
 
                                    struct share_mode_entry *e2)
1003
 
{
1004
 
        return (procid_equal(&e1->pid, &e2->pid) &&
1005
 
                (e1->op_mid == e2->op_mid) &&
1006
 
                (e1->dev == e2->dev) &&
1007
 
                (e1->inode == e2->inode));
1008
 
}
1009
 
 
1010
 
static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1011
 
                                                      struct share_mode_entry *entry)
1012
 
{
1013
 
        int i;
1014
 
 
1015
 
        for (i=0; i<lck->num_share_modes; i++) {
1016
 
                struct share_mode_entry *e = &lck->share_modes[i];
1017
 
                if (is_valid_share_mode_entry(entry) &&
1018
 
                    is_valid_share_mode_entry(e) &&
1019
 
                    share_modes_identical(e, entry)) {
1020
 
                        return e;
1021
 
                }
1022
 
                if (is_deferred_open_entry(entry) &&
1023
 
                    is_deferred_open_entry(e) &&
1024
 
                    deferred_open_identical(e, entry)) {
1025
 
                        return e;
1026
 
                }
1027
 
        }
1028
 
        return NULL;
1029
 
}
1030
 
 
1031
 
/*******************************************************************
1032
 
 Del the share mode of a file for this process. Return the number of
1033
 
 entries left.
1034
 
********************************************************************/
1035
 
 
1036
 
BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1037
 
{
1038
 
        struct share_mode_entry entry, *e;
1039
 
 
1040
 
        /* Don't care about the pid owner being correct here - just a search. */
1041
 
        fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1042
 
 
1043
 
        e = find_share_mode_entry(lck, &entry);
1044
 
        if (e == NULL) {
1045
 
                return False;
1046
 
        }
1047
 
 
1048
 
        e->op_type = UNUSED_SHARE_MODE_ENTRY;
1049
 
        lck->modified = True;
1050
 
        return True;
1051
 
}
1052
 
 
1053
 
void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
1054
 
{
1055
 
        struct share_mode_entry entry, *e;
1056
 
 
1057
 
        fill_deferred_open_entry(&entry, timeval_zero(),
1058
 
                                 lck->dev, lck->ino, mid);
1059
 
 
1060
 
        e = find_share_mode_entry(lck, &entry);
1061
 
        if (e == NULL) {
1062
 
                return;
1063
 
        }
1064
 
 
1065
 
        e->op_type = UNUSED_SHARE_MODE_ENTRY;
1066
 
        lck->modified = True;
1067
 
}
1068
 
 
1069
 
/*******************************************************************
1070
 
 Remove an oplock mid and mode entry from a share mode.
1071
 
********************************************************************/
1072
 
 
1073
 
BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1074
 
{
1075
 
        struct share_mode_entry entry, *e;
1076
 
 
1077
 
        /* Don't care about the pid owner being correct here - just a search. */
1078
 
        fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1079
 
 
1080
 
        e = find_share_mode_entry(lck, &entry);
1081
 
        if (e == NULL) {
1082
 
                return False;
1083
 
        }
1084
 
 
1085
 
        e->op_mid = 0;
1086
 
        e->op_type = NO_OPLOCK;
1087
 
        lck->modified = True;
1088
 
        return True;
1089
 
}
1090
 
 
1091
 
/*******************************************************************
1092
 
 Downgrade a oplock type from exclusive to level II.
1093
 
********************************************************************/
1094
 
 
1095
 
BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1096
 
{
1097
 
        struct share_mode_entry entry, *e;
1098
 
 
1099
 
        /* Don't care about the pid owner being correct here - just a search. */
1100
 
        fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1101
 
 
1102
 
        e = find_share_mode_entry(lck, &entry);
1103
 
        if (e == NULL) {
1104
 
                return False;
1105
 
        }
1106
 
 
1107
 
        e->op_type = LEVEL_II_OPLOCK;
1108
 
        lck->modified = True;
1109
 
        return True;
1110
 
}
1111
 
 
1112
 
/****************************************************************************
1113
 
 Deal with the internal needs of setting the delete on close flag. Note that
1114
 
 as the tdb locking is recursive, it is safe to call this from within 
1115
 
 open_file_ntcreate. JRA.
1116
 
****************************************************************************/
1117
 
 
1118
 
NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
1119
 
                                 uint32 dosmode)
1120
 
{
1121
 
        if (!delete_on_close) {
1122
 
                return NT_STATUS_OK;
1123
 
        }
1124
 
 
1125
 
        /*
1126
 
         * Only allow delete on close for writable files.
1127
 
         */
1128
 
 
1129
 
        if ((dosmode & aRONLY) &&
1130
 
            !lp_delete_readonly(SNUM(fsp->conn))) {
1131
 
                DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1132
 
                          "flag set but file attribute is readonly.\n",
1133
 
                          fsp->fsp_name ));
1134
 
                return NT_STATUS_CANNOT_DELETE;
1135
 
        }
1136
 
 
1137
 
        /*
1138
 
         * Only allow delete on close for writable shares.
1139
 
         */
1140
 
 
1141
 
        if (!CAN_WRITE(fsp->conn)) {
1142
 
                DEBUG(10,("can_set_delete_on_close: file %s delete on "
1143
 
                          "close flag set but write access denied on share.\n",
1144
 
                          fsp->fsp_name ));
1145
 
                return NT_STATUS_ACCESS_DENIED;
1146
 
        }
1147
 
 
1148
 
        /*
1149
 
         * Only allow delete on close for files/directories opened with delete
1150
 
         * intent.
1151
 
         */
1152
 
 
1153
 
        if (!(fsp->access_mask & DELETE_ACCESS)) {
1154
 
                DEBUG(10,("can_set_delete_on_close: file %s delete on "
1155
 
                          "close flag set but delete access denied.\n",
1156
 
                          fsp->fsp_name ));
1157
 
                return NT_STATUS_ACCESS_DENIED;
1158
 
        }
1159
 
 
1160
 
        return NT_STATUS_OK;
1161
 
}
1162
 
 
1163
 
/*************************************************************************
1164
 
 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1165
 
 (Should this be in locking.c.... ?).
1166
 
*************************************************************************/
1167
 
 
1168
 
static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
1169
 
{
1170
 
        UNIX_USER_TOKEN *cpy;
1171
 
 
1172
 
        if (tok == NULL) {
1173
 
                return NULL;
1174
 
        }
1175
 
 
1176
 
        cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1177
 
        if (!cpy) {
1178
 
                return NULL;
1179
 
        }
1180
 
 
1181
 
        cpy->uid = tok->uid;
1182
 
        cpy->gid = tok->gid;
1183
 
        cpy->ngroups = tok->ngroups;
1184
 
        if (tok->ngroups) {
1185
 
                /* Make this a talloc child of cpy. */
1186
 
                cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1187
 
                if (!cpy->groups) {
1188
 
                        return NULL;
1189
 
                }
1190
 
                memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1191
 
        }
1192
 
        return cpy;
1193
 
}
1194
 
 
1195
 
/****************************************************************************
1196
 
 Replace the delete on close token.
1197
 
****************************************************************************/
1198
 
 
1199
 
void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
1200
 
{
1201
 
        /* Ensure there's no token. */
1202
 
        if (lck->delete_token) {
1203
 
                TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
1204
 
                lck->delete_token = NULL;
1205
 
        }
1206
 
 
1207
 
        /* Copy the new token (can be NULL). */
1208
 
        lck->delete_token = copy_unix_token(lck, tok);
1209
 
        lck->modified = True;
1210
 
}
1211
 
 
1212
 
/****************************************************************************
1213
 
 Sets the delete on close flag over all share modes on this file.
1214
 
 Modify the share mode entry for all files open
1215
 
 on this device and inode to tell other smbds we have
1216
 
 changed the delete on close flag. This will be noticed
1217
 
 in the close code, the last closer will delete the file
1218
 
 if flag is set.
1219
 
 Note that setting this to any value clears the initial_delete_on_close flag.
1220
 
 If delete_on_close is True this makes a copy of any UNIX_USER_TOKEN into the
1221
 
 lck entry.
1222
 
****************************************************************************/
1223
 
 
1224
 
BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
1225
 
{
1226
 
        struct share_mode_lock *lck;
1227
 
        
1228
 
        DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1229
 
                  "fnum = %d, file %s\n",
1230
 
                  delete_on_close ? "Adding" : "Removing", fsp->fnum,
1231
 
                  fsp->fsp_name ));
1232
 
 
1233
 
        if (fsp->is_stat) {
1234
 
                return True;
1235
 
        }
1236
 
 
1237
 
        lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
1238
 
        if (lck == NULL) {
1239
 
                return False;
1240
 
        }
1241
 
 
1242
 
        if (lck->delete_on_close != delete_on_close) {
1243
 
                set_delete_on_close_token(lck, tok);
1244
 
                lck->delete_on_close = delete_on_close;
1245
 
                if (delete_on_close) {
1246
 
                        SMB_ASSERT(lck->delete_token != NULL);
1247
 
                }
1248
 
                lck->modified = True;
1249
 
        }
1250
 
 
1251
 
        if (lck->initial_delete_on_close) {
1252
 
                lck->initial_delete_on_close = False;
1253
 
                lck->modified = True;
1254
 
        }
1255
 
 
1256
 
        TALLOC_FREE(lck);
1257
 
        return True;
1258
 
}
1259
 
 
1260
 
static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, 
1261
 
                       void *state)
1262
 
{
1263
 
        struct locking_data *data;
1264
 
        struct share_mode_entry *shares;
1265
 
        const char *sharepath;
1266
 
        const char *fname;
1267
 
        int i;
1268
 
        LOCKING_FN(traverse_callback) = (LOCKING_FN_CAST())state;
1269
 
 
1270
 
        /* Ensure this is a locking_key record. */
1271
 
        if (kbuf.dsize != sizeof(struct locking_key))
1272
 
                return 0;
1273
 
 
1274
 
        data = (struct locking_data *)dbuf.dptr;
1275
 
        shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
1276
 
        sharepath = dbuf.dptr + sizeof(*data) +
1277
 
                data->u.s.num_share_mode_entries*sizeof(*shares) +
1278
 
                data->u.s.delete_token_size;
1279
 
        fname = dbuf.dptr + sizeof(*data) +
1280
 
                data->u.s.num_share_mode_entries*sizeof(*shares) +
1281
 
                data->u.s.delete_token_size +
1282
 
                strlen(sharepath) + 1;
1283
 
 
1284
 
        for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1285
 
                traverse_callback(&shares[i], sharepath, fname);
1286
 
        }
1287
 
        return 0;
1288
 
}
1289
 
 
1290
 
/*******************************************************************
1291
 
 Call the specified function on each entry under management by the
1292
 
 share mode system.
1293
 
********************************************************************/
1294
 
 
1295
 
int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *))
1296
 
{
1297
 
        if (tdb == NULL)
1298
 
                return 0;
1299
 
        return tdb_traverse(tdb, traverse_fn, (void *)fn);
1300
 
}