r4108: As check_self is *always* False in every invokation, remove the
[samba.git] / source3 / locking / locking.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Locking functions
4    Copyright (C) Andrew Tridgell 1992-2000
5    Copyright (C) Jeremy Allison 1992-2000
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21    Revision History:
22
23    12 aug 96: Erik.Devriendt@te6.siemens.be
24    added support for shared memory implementation of share mode locking
25
26    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27    locking to deal with multiple share modes per open file.
28
29    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30    support.
31
32    rewrtten completely to use new tdb code. Tridge, Dec '99
33
34    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35 */
36
37 #include "includes.h"
38 uint16 global_smbpid;
39
40 /* the locking database handle */
41 static TDB_CONTEXT *tdb;
42
43 struct locking_data {
44         union {
45                 int num_share_mode_entries;
46                 share_mode_entry dummy; /* Needed for alignment. */
47         } u;
48         /* the following two entries are implicit
49            share_mode_entry modes[num_share_mode_entries];
50            char file_name[];
51         */
52 };
53
54 /****************************************************************************
55  Debugging aid :-).
56 ****************************************************************************/
57
58 static const char *lock_type_name(enum brl_type lock_type)
59 {
60         return (lock_type == READ_LOCK) ? "READ" : "WRITE";
61 }
62
63 /****************************************************************************
64  Utility function called to see if a file region is locked.
65 ****************************************************************************/
66
67 BOOL is_locked(files_struct *fsp,connection_struct *conn,
68                SMB_BIG_UINT count,SMB_BIG_UINT offset, 
69                enum brl_type lock_type)
70 {
71         int snum = SNUM(conn);
72         BOOL ret;
73         
74         if (count == 0)
75                 return(False);
76
77         if (!lp_locking(snum) || !lp_strict_locking(snum))
78                 return(False);
79
80         ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
81                              global_smbpid, sys_getpid(), conn->cnum, 
82                              offset, count, lock_type);
83
84         DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
85                         (double)offset, (double)count, ret ? "locked" : "unlocked",
86                         fsp->fsp_name ));
87
88         /*
89          * There is no lock held by an SMB daemon, check to
90          * see if there is a POSIX lock from a UNIX or NFS process.
91          */
92
93         if(!ret && lp_posix_locking(snum)) {
94                 ret = is_posix_locked(fsp, offset, count, lock_type);
95
96                 DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n",
97                                 (double)offset, (double)count, ret ? "locked" : "unlocked",
98                                 fsp->fsp_name ));
99         }
100
101         return ret;
102 }
103
104 /****************************************************************************
105  Utility function called by locking requests.
106 ****************************************************************************/
107
108 static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
109                  SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
110 {
111         NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
112
113         if (!lp_locking(SNUM(conn)))
114                 return NT_STATUS_OK;
115
116         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
117
118         DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
119                   lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
120
121         if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
122                 status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
123                                   lock_pid, sys_getpid(), conn->cnum, 
124                                   offset, count, 
125                                   lock_type, my_lock_ctx);
126
127                 if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {
128
129                         /*
130                          * Try and get a POSIX lock on this range.
131                          * Note that this is ok if it is a read lock
132                          * overlapping on a different fd. JRA.
133                          */
134
135                         if (!set_posix_lock(fsp, offset, count, lock_type)) {
136                                 if (errno == EACCES || errno == EAGAIN)
137                                         status = NT_STATUS_FILE_LOCK_CONFLICT;
138                                 else
139                                         status = map_nt_error_from_unix(errno);
140
141                                 /*
142                                  * We failed to map - we must now remove the brl
143                                  * lock entry.
144                                  */
145                                 (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
146                                                                 lock_pid, sys_getpid(), conn->cnum, 
147                                                                 offset, count, False,
148                                                                 NULL, NULL);
149                         }
150                 }
151         }
152
153         return status;
154 }
155
156 /****************************************************************************
157  Utility function called by locking requests. This is *DISGUSTING*. It also
158  appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
159  is so slow on the locking tests...... ? This is the reason. Much though I hate
160  it, we need this. JRA.
161 ****************************************************************************/
162
163 NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
164                  SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
165 {
166         int j, maxj = lp_lock_spin_count();
167         int sleeptime = lp_lock_sleep_time();
168         NTSTATUS status, ret;
169
170         if (maxj <= 0)
171                 maxj = 1;
172
173         ret = NT_STATUS_OK; /* to keep dumb compilers happy */
174
175         for (j = 0; j < maxj; j++) {
176                 status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx);
177                 if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
178                     !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
179                         return status;
180                 }
181                 /* if we do fail then return the first error code we got */
182                 if (j == 0) {
183                         ret = status;
184                         /* Don't spin if we blocked ourselves. */
185                         if (*my_lock_ctx)
186                                 return ret;
187                 }
188                 if (sleeptime)
189                         sys_usleep(sleeptime);
190         }
191         return ret;
192 }
193
194 /* Struct passed to brl_unlock. */
195 struct posix_unlock_data_struct {
196         files_struct *fsp;
197         SMB_BIG_UINT offset;
198         SMB_BIG_UINT count;
199 };
200
201 /****************************************************************************
202  Function passed to brl_unlock to allow POSIX unlock to be done first.
203 ****************************************************************************/
204
205 static void posix_unlock(void *pre_data)
206 {
207         struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data;
208
209         if (lp_posix_locking(SNUM(pdata->fsp->conn)))
210                 release_posix_lock(pdata->fsp, pdata->offset, pdata->count);
211 }
212
213 /****************************************************************************
214  Utility function called by unlocking requests.
215 ****************************************************************************/
216
217 NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
218                    SMB_BIG_UINT count,SMB_BIG_UINT offset)
219 {
220         BOOL ok = False;
221         struct posix_unlock_data_struct posix_data;
222         
223         if (!lp_locking(SNUM(conn)))
224                 return NT_STATUS_OK;
225         
226         if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
227                 return NT_STATUS_INVALID_HANDLE;
228         }
229         
230         DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
231                   (double)offset, (double)count, fsp->fsp_name ));
232
233         /*
234          * Remove the existing lock record from the tdb lockdb
235          * before looking at POSIX locks. If this record doesn't
236          * match then don't bother looking to remove POSIX locks.
237          */
238
239         posix_data.fsp = fsp;
240         posix_data.offset = offset;
241         posix_data.count = count;
242
243         ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
244                         lock_pid, sys_getpid(), conn->cnum, offset, count,
245                         False, posix_unlock, (void *)&posix_data);
246    
247         if (!ok) {
248                 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
249                 return NT_STATUS_RANGE_NOT_LOCKED;
250         }
251         return NT_STATUS_OK;
252 }
253
254 /****************************************************************************
255  Remove any locks on this fd. Called from file_close().
256 ****************************************************************************/
257
258 void locking_close_file(files_struct *fsp)
259 {
260         pid_t pid = sys_getpid();
261
262         if (!lp_locking(SNUM(fsp->conn)))
263                 return;
264
265         /*
266          * Just release all the brl locks, no need to release individually.
267          */
268
269         brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum);
270
271         if(lp_posix_locking(SNUM(fsp->conn))) {
272
273                 /* 
274                  * Release all the POSIX locks.
275                  */
276                 posix_locking_close_file(fsp);
277
278         }
279 }
280
281 /****************************************************************************
282  Initialise the locking functions.
283 ****************************************************************************/
284
285 static int open_read_only;
286
287 BOOL locking_init(int read_only)
288 {
289         brl_init(read_only);
290
291         if (tdb)
292                 return True;
293
294         tdb = tdb_open_log(lock_path("locking.tdb"), 
295                        0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), 
296                        read_only?O_RDONLY:O_RDWR|O_CREAT,
297                        0644);
298
299         if (!tdb) {
300                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
301                 return False;
302         }
303         
304         if (!posix_locking_init(read_only))
305                 return False;
306
307         open_read_only = read_only;
308
309         return True;
310 }
311
312 /*******************************************************************
313  Deinitialize the share_mode management.
314 ******************************************************************/
315
316 BOOL locking_end(void)
317 {
318
319         brl_shutdown(open_read_only);
320         if (tdb) {
321
322                 if (tdb_close(tdb) != 0)
323                         return False;
324         }
325
326         return True;
327 }
328
329 /*******************************************************************
330  Form a static locking key for a dev/inode pair.
331 ******************************************************************/
332
333 static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
334 {
335         static struct locking_key key;
336         TDB_DATA kbuf;
337
338         memset(&key, '\0', sizeof(key));
339         key.dev = dev;
340         key.inode = inode;
341         kbuf.dptr = (char *)&key;
342         kbuf.dsize = sizeof(key);
343         return kbuf;
344 }
345
346 static TDB_DATA locking_key_fsp(files_struct *fsp)
347 {
348         return locking_key(fsp->dev, fsp->inode);
349 }
350
351 /*******************************************************************
352  Lock a hash bucket entry.
353 ******************************************************************/
354
355 BOOL lock_share_entry(connection_struct *conn,
356                       SMB_DEV_T dev, SMB_INO_T inode)
357 {
358         return tdb_chainlock(tdb, locking_key(dev, inode)) == 0;
359 }
360
361 /*******************************************************************
362  Unlock a hash bucket entry.
363 ******************************************************************/
364
365 void unlock_share_entry(connection_struct *conn,
366                         SMB_DEV_T dev, SMB_INO_T inode)
367 {
368         tdb_chainunlock(tdb, locking_key(dev, inode));
369 }
370
371 /*******************************************************************
372  Lock a hash bucket entry. use a fsp for convenience
373 ******************************************************************/
374
375 BOOL lock_share_entry_fsp(files_struct *fsp)
376 {
377         return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
378 }
379
380 /*******************************************************************
381  Unlock a hash bucket entry.
382 ******************************************************************/
383
384 void unlock_share_entry_fsp(files_struct *fsp)
385 {
386         tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode));
387 }
388
389 /*******************************************************************
390  Print out a share mode.
391 ********************************************************************/
392
393 char *share_mode_str(int num, share_mode_entry *e)
394 {
395         static pstring share_str;
396
397         slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \
398 pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
399         num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
400         (unsigned int)e->dev, (double)e->inode );
401
402         return share_str;
403 }
404
405 /*******************************************************************
406  Print out a share mode table.
407 ********************************************************************/
408
409 static void print_share_mode_table(struct locking_data *data)
410 {
411         int num_share_modes = data->u.num_share_mode_entries;
412         share_mode_entry *shares = (share_mode_entry *)(data + 1);
413         int i;
414
415         for (i = 0; i < num_share_modes; i++) {
416                 share_mode_entry *entry_p = &shares[i];
417                 DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, entry_p) ));
418         }
419 }
420
421 /*******************************************************************
422  Get all share mode entries for a dev/inode pair.
423 ********************************************************************/
424
425 int get_share_modes(connection_struct *conn, 
426                     SMB_DEV_T dev, SMB_INO_T inode, 
427                     share_mode_entry **pp_shares)
428 {
429         TDB_DATA dbuf;
430         struct locking_data *data;
431         int num_share_modes;
432         share_mode_entry *shares = NULL;
433         TDB_DATA key = locking_key(dev, inode);
434         *pp_shares = NULL;
435
436         dbuf = tdb_fetch(tdb, key);
437         if (!dbuf.dptr)
438                 return 0;
439
440         data = (struct locking_data *)dbuf.dptr;
441         num_share_modes = data->u.num_share_mode_entries;
442         if(num_share_modes) {
443                 pstring fname;
444                 int i;
445                 int del_count = 0;
446
447                 shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data),  
448                                                 num_share_modes * sizeof(share_mode_entry));
449
450                 if (!shares) {
451                         SAFE_FREE(dbuf.dptr);
452                         return 0;
453                 }
454
455                 /* Save off the associated filename. */
456                 pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry));
457
458                 /*
459                  * Ensure that each entry has a real process attached.
460                  */
461
462                 for (i = 0; i < num_share_modes; ) {
463                         share_mode_entry *entry_p = &shares[i];
464                         if (process_exists(entry_p->pid)) {
465                                 DEBUG(10,("get_share_modes: %s\n", share_mode_str(i, entry_p) ));
466                                 i++;
467                         } else {
468                                 DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) ));
469                                 if (num_share_modes - i - 1 > 0) {
470                                         memcpy( &shares[i], &shares[i+1],
471                                                 sizeof(share_mode_entry) * (num_share_modes - i - 1));
472                                 }
473                                 num_share_modes--;
474                                 del_count++;
475                         }
476                 }
477
478                 /* Did we delete any ? If so, re-store in tdb. */
479                 if (del_count) {
480                         data->u.num_share_mode_entries = num_share_modes;
481                         
482                         if (num_share_modes) {
483                                 memcpy(dbuf.dptr + sizeof(*data), shares,
484                                                 num_share_modes * sizeof(share_mode_entry));
485                                 /* Append the filename. */
486                                 pstrcpy(dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry), fname);
487                         }
488
489                         /* The record has shrunk a bit */
490                         dbuf.dsize -= del_count * sizeof(share_mode_entry);
491
492                         if (data->u.num_share_mode_entries == 0) {
493                                 if (tdb_delete(tdb, key) == -1) {
494                                         SAFE_FREE(shares);
495                                         SAFE_FREE(dbuf.dptr);
496                                         return 0;
497                                 }
498                         } else {
499                                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
500                                         SAFE_FREE(shares);
501                                         SAFE_FREE(dbuf.dptr);
502                                         return 0;
503                                 }
504                         }
505                 }
506         }
507
508         SAFE_FREE(dbuf.dptr);
509         *pp_shares = shares;
510         return num_share_modes;
511 }
512
513 /*******************************************************************
514  Fill a share mode entry.
515 ********************************************************************/
516
517 static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type)
518 {
519         share_mode_entry *e = (share_mode_entry *)p;
520         void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */
521
522         memset(e, '\0', sizeof(share_mode_entry));
523         e->pid = sys_getpid();
524         e->share_mode = fsp->share_mode;
525         e->desired_access = fsp->desired_access;
526         e->op_port = port;
527         e->op_type = op_type;
528         memcpy(x, &fsp->open_time, sizeof(struct timeval));
529         e->share_file_id = fsp->file_id;
530         e->dev = fsp->dev;
531         e->inode = fsp->inode;
532 }
533
534 /*******************************************************************
535  Check if two share mode entries are identical, ignoring oplock 
536  and port info and desired_access.
537 ********************************************************************/
538
539 BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
540 {
541 #if 1 /* JRA PARANOIA TEST - REMOVE LATER */
542         if (e1->pid == e2->pid &&
543                 e1->share_file_id == e2->share_file_id &&
544                 e1->dev == e2->dev &&
545                 e1->inode == e2->inode &&
546                 (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) {
547                         DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
548                                 (unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG),
549                                 (unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) ));
550                 smb_panic("PANIC: share_modes_identical logic error.\n");
551         }
552 #endif
553
554         return (e1->pid == e2->pid &&
555                 (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
556                 e1->dev == e2->dev &&
557                 e1->inode == e2->inode &&
558                 e1->share_file_id == e2->share_file_id );
559 }
560
561 /*******************************************************************
562  Delete a specific share mode. Return the number
563  of entries left, and a memdup'ed copy of the entry deleted (if required).
564  Ignore if no entry deleted.
565 ********************************************************************/
566
567 ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
568                         share_mode_entry *entry, share_mode_entry **ppse)
569 {
570         TDB_DATA dbuf;
571         struct locking_data *data;
572         int i, del_count=0;
573         share_mode_entry *shares;
574         ssize_t count = 0;
575         TDB_DATA key = locking_key(dev, inode);
576
577         if (ppse)
578                 *ppse = NULL;
579
580         /* read in the existing share modes */
581         dbuf = tdb_fetch(tdb, key);
582         if (!dbuf.dptr)
583                 return -1;
584
585         data = (struct locking_data *)dbuf.dptr;
586         shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
587
588         /*
589          * Find any with this pid and delete it
590          * by overwriting with the rest of the data 
591          * from the record.
592          */
593
594         DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries ));
595
596         for (i=0;i<data->u.num_share_mode_entries;) {
597                 if (share_modes_identical(&shares[i], entry)) {
598                         DEBUG(10,("del_share_entry: deleted %s\n",
599                                 share_mode_str(i, &shares[i]) ));
600                         if (ppse)
601                                 *ppse = memdup(&shares[i], sizeof(*shares));
602                         data->u.num_share_mode_entries--;
603                         if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) {
604                                 memmove(&shares[i], &shares[i+1], 
605                                         dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
606                         }
607                         del_count++;
608
609                         DEBUG(10,("del_share_entry: deleting entry %d\n", i ));
610
611                 } else {
612                         i++;
613                 }
614         }
615
616         if (del_count) {
617                 /* the record may have shrunk a bit */
618                 dbuf.dsize -= del_count * sizeof(*shares);
619
620                 count = (ssize_t)data->u.num_share_mode_entries;
621
622                 /* store it back in the database */
623                 if (data->u.num_share_mode_entries == 0) {
624                         if (tdb_delete(tdb, key) == -1)
625                                 count = -1;
626                 } else {
627                         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
628                                 count = -1;
629                 }
630         }
631         DEBUG(10,("del_share_entry: Remaining table.\n"));
632         print_share_mode_table((struct locking_data *)dbuf.dptr);
633         SAFE_FREE(dbuf.dptr);
634         return count;
635 }
636
637 /*******************************************************************
638  Del the share mode of a file for this process. Return the number
639  of entries left, and a memdup'ed copy of the entry deleted.
640 ********************************************************************/
641
642 ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse)
643 {
644         share_mode_entry entry;
645
646         /*
647          * Fake up a share_mode_entry for comparisons.
648          */
649
650         fill_share_mode((char *)&entry, fsp, 0, 0);
651         return del_share_entry(fsp->dev, fsp->inode, &entry, ppse);
652 }
653
654 /*******************************************************************
655  Set the share mode of a file. Return False on fail, True on success.
656 ********************************************************************/
657
658 BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
659 {
660         TDB_DATA dbuf;
661         struct locking_data *data;
662         char *p=NULL;
663         int size;
664         TDB_DATA key = locking_key_fsp(fsp);
665         BOOL ret = True;
666                 
667         /* read in the existing share modes if any */
668         dbuf = tdb_fetch(tdb, key);
669         if (!dbuf.dptr) {
670                 size_t offset;
671                 /* we'll need to create a new record */
672                 pstring fname;
673
674                 pstrcpy(fname, fsp->conn->connectpath);
675                 pstrcat(fname, "/");
676                 pstrcat(fname, fsp->fsp_name);
677
678                 size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1;
679                 p = (char *)SMB_MALLOC(size);
680                 if (!p)
681                         return False;
682                 data = (struct locking_data *)p;
683                 data->u.num_share_mode_entries = 1;
684         
685                 DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n",
686                         fsp->fsp_name ));
687
688                 offset = sizeof(*data) + sizeof(share_mode_entry);
689                 safe_strcpy(p + offset, fname, size - offset - 1);
690                 fill_share_mode(p + sizeof(*data), fsp, port, op_type);
691                 dbuf.dptr = p;
692                 dbuf.dsize = size;
693                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
694                         ret = False;
695
696                 print_share_mode_table((struct locking_data *)p);
697
698                 SAFE_FREE(p);
699                 return ret;
700         }
701
702         /* we're adding to an existing entry - this is a bit fiddly */
703         data = (struct locking_data *)dbuf.dptr;
704
705         data->u.num_share_mode_entries++;
706         
707         DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n",
708                 fsp->fsp_name, data->u.num_share_mode_entries ));
709
710         size = dbuf.dsize + sizeof(share_mode_entry);
711         p = SMB_MALLOC(size);
712         if (!p) {
713                 SAFE_FREE(dbuf.dptr);
714                 return False;
715         }
716         memcpy(p, dbuf.dptr, sizeof(*data));
717         fill_share_mode(p + sizeof(*data), fsp, port, op_type);
718         memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data),
719                dbuf.dsize - sizeof(*data));
720         SAFE_FREE(dbuf.dptr);
721         dbuf.dptr = p;
722         dbuf.dsize = size;
723         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
724                 ret = False;
725         print_share_mode_table((struct locking_data *)p);
726         SAFE_FREE(p);
727         return ret;
728 }
729
730 /*******************************************************************
731  A generic in-place modification call for share mode entries.
732 ********************************************************************/
733
734 static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry,
735                            void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
736                            void *param)
737 {
738         TDB_DATA dbuf;
739         struct locking_data *data;
740         int i;
741         share_mode_entry *shares;
742         BOOL need_store=False;
743         BOOL ret = True;
744         TDB_DATA key = locking_key(dev, inode);
745
746         /* read in the existing share modes */
747         dbuf = tdb_fetch(tdb, key);
748         if (!dbuf.dptr)
749                 return False;
750
751         data = (struct locking_data *)dbuf.dptr;
752         shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
753
754         /* find any with our pid and call the supplied function */
755         for (i=0;i<data->u.num_share_mode_entries;i++) {
756                 if (share_modes_identical(entry, &shares[i])) {
757                         mod_fn(&shares[i], dev, inode, param);
758                         need_store=True;
759                 }
760         }
761
762         /* if the mod fn was called then store it back */
763         if (need_store) {
764                 if (data->u.num_share_mode_entries == 0) {
765                         if (tdb_delete(tdb, key) == -1)
766                                 ret = False;
767                 } else {
768                         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
769                                 ret = False;
770                 }
771         }
772
773         SAFE_FREE(dbuf.dptr);
774         return ret;
775 }
776
777 /*******************************************************************
778  Static function that actually does the work for the generic function
779  below.
780 ********************************************************************/
781
782 static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, 
783                                    void *param)
784 {
785         DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
786                   (unsigned int)dev, (double)inode ));
787         /* Delete the oplock info. */
788         entry->op_port = 0;
789         entry->op_type = NO_OPLOCK;
790 }
791
792 /*******************************************************************
793  Remove an oplock port and mode entry from a share mode.
794 ********************************************************************/
795
796 BOOL remove_share_oplock(files_struct *fsp)
797 {
798         share_mode_entry entry;
799         /*
800          * Fake up an entry for comparisons...
801          */
802         fill_share_mode((char *)&entry, fsp, 0, 0);
803         return mod_share_mode(fsp->dev, fsp->inode, &entry, remove_share_oplock_fn, NULL);
804 }
805
806 /*******************************************************************
807  Static function that actually does the work for the generic function
808  below.
809 ********************************************************************/
810
811 static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, 
812                                    void *param)
813 {
814         DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n",
815                   (unsigned int)dev, (double)inode ));
816         entry->op_type = LEVEL_II_OPLOCK;
817 }
818
819 /*******************************************************************
820  Downgrade a oplock type from exclusive to level II.
821 ********************************************************************/
822
823 BOOL downgrade_share_oplock(files_struct *fsp)
824 {
825         share_mode_entry entry;
826         /*
827          * Fake up an entry for comparisons...
828          */
829         fill_share_mode((char *)&entry, fsp, 0, 0);
830         return mod_share_mode(fsp->dev, fsp->inode, &entry, downgrade_share_oplock_fn, NULL);
831 }
832
833 /*******************************************************************
834  Get/Set the delete on close flag in a set of share modes.
835  Return False on fail, True on success.
836 ********************************************************************/
837
838 BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
839 {
840         TDB_DATA dbuf;
841         struct locking_data *data;
842         int i;
843         share_mode_entry *shares;
844         TDB_DATA key = locking_key(dev, inode);
845
846         /* read in the existing share modes */
847         dbuf = tdb_fetch(tdb, key);
848         if (!dbuf.dptr)
849                 return False;
850
851         data = (struct locking_data *)dbuf.dptr;
852         shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
853
854         /* Set/Unset the delete on close element. */
855         for (i=0;i<data->u.num_share_mode_entries;i++,shares++) {
856                 shares->share_mode = (delete_on_close ?
857                             (shares->share_mode | DELETE_ON_CLOSE_FLAG) :
858                             (shares->share_mode & ~DELETE_ON_CLOSE_FLAG) );
859         }
860
861         /* store it back */
862         if (data->u.num_share_mode_entries) {
863                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) {
864                         SAFE_FREE(dbuf.dptr);
865                         return False;
866                 }
867         }
868
869         SAFE_FREE(dbuf.dptr);
870         return True;
871 }
872
873 /*******************************************************************
874  Print out a deferred open entry.
875 ********************************************************************/
876
877 char *deferred_open_str(int num, deferred_open_entry *e)
878 {
879         static pstring de_str;
880
881         slprintf(de_str, sizeof(de_str)-1, "deferred_open_entry[%d]: \
882 pid = %lu, mid = %u, dev = 0x%x, inode = %.0f, port = %u, time = [%u.%06u]",
883                 num, (unsigned long)e->pid, (unsigned int)e->mid, (unsigned int)e->dev, (double)e->inode,
884                 (unsigned int)e->port,
885                 (unsigned int)e->time.tv_sec, (unsigned int)e->time.tv_usec );
886
887         return de_str;
888 }
889
890 /* Internal data structures for deferred opens... */
891
892 struct de_locking_key {
893         char name[4];
894         SMB_DEV_T dev;
895         SMB_INO_T inode;
896 };
897
898 struct deferred_open_data {
899         union {
900                 int num_deferred_open_entries;
901                 deferred_open_entry dummy; /* Needed for alignment. */
902         } u;
903         /* the following two entries are implicit
904            deferred_open_entry de_entries[num_deferred_open_entries];
905            char file_name[];
906         */
907 };
908
909 /*******************************************************************
910  Print out a deferred open table.
911 ********************************************************************/
912
913 static void print_deferred_open_table(struct deferred_open_data *data)
914 {
915         int num_de_entries = data->u.num_deferred_open_entries;
916         deferred_open_entry *de_entries = (deferred_open_entry *)(data + 1);
917         int i;
918
919         for (i = 0; i < num_de_entries; i++) {
920                 deferred_open_entry *entry_p = &de_entries[i];
921                 DEBUG(10,("print_deferred_open_table: %s\n", deferred_open_str(i, entry_p) ));
922         }
923 }
924
925
926 /*******************************************************************
927  Form a static deferred open locking key for a dev/inode pair.
928 ******************************************************************/
929
930 static TDB_DATA deferred_open_locking_key(SMB_DEV_T dev, SMB_INO_T inode)
931 {
932         static struct de_locking_key key;
933         TDB_DATA kbuf;
934
935         memset(&key, '\0', sizeof(key));
936         memcpy(&key.name[0], "DOE", 4);
937         key.dev = dev;
938         key.inode = inode;
939         kbuf.dptr = (char *)&key;
940         kbuf.dsize = sizeof(key);
941         return kbuf;
942 }
943
944 /*******************************************************************
945  Get all deferred open entries for a dev/inode pair.
946 ********************************************************************/
947
948 int get_deferred_opens(connection_struct *conn, 
949                     SMB_DEV_T dev, SMB_INO_T inode, 
950                     deferred_open_entry **pp_de_entries)
951 {
952         TDB_DATA dbuf;
953         struct deferred_open_data *data;
954         int num_de_entries;
955         deferred_open_entry *de_entries = NULL;
956         TDB_DATA key = deferred_open_locking_key(dev, inode);
957
958         *pp_de_entries = NULL;
959
960         dbuf = tdb_fetch(tdb, key);
961         if (!dbuf.dptr)
962                 return 0;
963
964         data = (struct deferred_open_data *)dbuf.dptr;
965         num_de_entries = data->u.num_deferred_open_entries;
966         if(num_de_entries) {
967                 pstring fname;
968                 int i;
969                 int del_count = 0;
970
971                 de_entries = (deferred_open_entry *)memdup(dbuf.dptr + sizeof(*data),   
972                                                 num_de_entries * sizeof(deferred_open_entry));
973
974                 if (!de_entries) {
975                         SAFE_FREE(dbuf.dptr);
976                         return 0;
977                 }
978
979                 /* Save off the associated filename. */
980                 pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry));
981
982                 /*
983                  * Ensure that each entry has a real process attached.
984                  */
985
986                 for (i = 0; i < num_de_entries; ) {
987                         deferred_open_entry *entry_p = &de_entries[i];
988                         if (process_exists(entry_p->pid)) {
989                                 DEBUG(10,("get_deferred_opens: %s\n", deferred_open_str(i, entry_p) ));
990                                 i++;
991                         } else {
992                                 DEBUG(10,("get_deferred_opens: deleted %s\n", deferred_open_str(i, entry_p) ));
993                                 if (num_de_entries - i - 1 > 0) {
994                                         memcpy( &de_entries[i], &de_entries[i+1],
995                                                 sizeof(deferred_open_entry) * (num_de_entries - i - 1));
996                                 }
997                                 num_de_entries--;
998                                 del_count++;
999                         }
1000                 }
1001
1002                 /* Did we delete any ? If so, re-store in tdb. */
1003                 if (del_count) {
1004                         data->u.num_deferred_open_entries = num_de_entries;
1005                         
1006                         if (num_de_entries) {
1007                                 memcpy(dbuf.dptr + sizeof(*data), de_entries,
1008                                                 num_de_entries * sizeof(deferred_open_entry));
1009                                 /* Append the filename. */
1010                                 pstrcpy(dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry), fname);
1011                         }
1012
1013                         /* The record has shrunk a bit */
1014                         dbuf.dsize -= del_count * sizeof(deferred_open_entry);
1015
1016                         if (data->u.num_deferred_open_entries == 0) {
1017                                 if (tdb_delete(tdb, key) == -1) {
1018                                         SAFE_FREE(de_entries);
1019                                         SAFE_FREE(dbuf.dptr);
1020                                         return 0;
1021                                 }
1022                         } else {
1023                                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
1024                                         SAFE_FREE(de_entries);
1025                                         SAFE_FREE(dbuf.dptr);
1026                                         return 0;
1027                                 }
1028                         }
1029                 }
1030         }
1031
1032         SAFE_FREE(dbuf.dptr);
1033         *pp_de_entries = de_entries;
1034         return num_de_entries;
1035 }
1036
1037 /*******************************************************************
1038  Check if two deferred open entries are identical.
1039 ********************************************************************/
1040
1041 static BOOL deferred_open_entries_identical( deferred_open_entry *e1, deferred_open_entry *e2)
1042 {
1043         return (e1->pid == e2->pid &&
1044                 e1->mid == e2->mid &&
1045                 e1->port == e2->port &&
1046                 e1->dev == e2->dev &&
1047                 e1->inode == e2->inode &&
1048                 e1->time.tv_sec == e2->time.tv_sec &&
1049                 e1->time.tv_usec == e2->time.tv_usec);
1050 }
1051
1052 /*******************************************************************
1053  Delete a specific deferred open entry.
1054  Ignore if no entry deleted.
1055 ********************************************************************/
1056
1057 BOOL delete_deferred_open_entry(deferred_open_entry *entry)
1058 {
1059         TDB_DATA dbuf;
1060         struct deferred_open_data *data;
1061         int i, del_count=0;
1062         deferred_open_entry *de_entries;
1063         BOOL ret = True;
1064         TDB_DATA key = deferred_open_locking_key(entry->dev, entry->inode);
1065
1066         /* read in the existing share modes */
1067         dbuf = tdb_fetch(tdb, key);
1068         if (!dbuf.dptr)
1069                 return -1;
1070
1071         data = (struct deferred_open_data *)dbuf.dptr;
1072         de_entries = (deferred_open_entry *)(dbuf.dptr + sizeof(*data));
1073
1074         /*
1075          * Find any with this pid and delete it
1076          * by overwriting with the rest of the data 
1077          * from the record.
1078          */
1079
1080         DEBUG(10,("delete_deferred_open_entry: num_deferred_open_entries = %d\n",
1081                 data->u.num_deferred_open_entries ));
1082
1083         for (i=0;i<data->u.num_deferred_open_entries;) {
1084                 if (deferred_open_entries_identical(&de_entries[i], entry)) {
1085                         DEBUG(10,("delete_deferred_open_entry: deleted %s\n",
1086                                 deferred_open_str(i, &de_entries[i]) ));
1087
1088                         data->u.num_deferred_open_entries--;
1089                         if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries))) > 0) {
1090                                 memmove(&de_entries[i], &de_entries[i+1], 
1091                                         dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries)));
1092                         }
1093                         del_count++;
1094
1095                         DEBUG(10,("delete_deferred_open_entry: deleting entry %d\n", i ));
1096
1097                 } else {
1098                         i++;
1099                 }
1100         }
1101
1102         SMB_ASSERT(del_count == 0 || del_count == 1);
1103
1104         if (del_count) {
1105                 /* the record may have shrunk a bit */
1106                 dbuf.dsize -= del_count * sizeof(*de_entries);
1107
1108                 /* store it back in the database */
1109                 if (data->u.num_deferred_open_entries == 0) {
1110                         if (tdb_delete(tdb, key) == -1)
1111                                 ret = False;
1112                 } else {
1113                         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
1114                                 ret = False;
1115                 }
1116         }
1117         DEBUG(10,("delete_deferred_open_entry: Remaining table.\n"));
1118         print_deferred_open_table((struct deferred_open_data*)dbuf.dptr);
1119         SAFE_FREE(dbuf.dptr);
1120         return ret;
1121 }
1122
1123 /*******************************************************************
1124  Fill a deferred open entry.
1125 ********************************************************************/
1126
1127 static void fill_deferred_open(char *p, uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port)
1128 {
1129         deferred_open_entry *e = (deferred_open_entry *)p;
1130         void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */
1131
1132         memset(e, '\0', sizeof(deferred_open_entry));
1133         e->mid = mid;
1134         e->pid = sys_getpid();
1135         memcpy(x, ptv, sizeof(struct timeval));
1136         e->dev = dev;
1137         e->inode = inode;
1138         e->port = port;
1139 }
1140
1141 /*******************************************************************
1142  Add a deferred open record. Return False on fail, True on success.
1143 ********************************************************************/
1144
1145 BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port, const char *fname)
1146 {
1147         TDB_DATA dbuf;
1148         struct deferred_open_data *data;
1149         char *p=NULL;
1150         int size;
1151         TDB_DATA key = deferred_open_locking_key(dev, inode);
1152         BOOL ret = True;
1153                 
1154         /* read in the existing deferred open records if any */
1155         dbuf = tdb_fetch(tdb, key);
1156         if (!dbuf.dptr) {
1157                 size_t offset;
1158                 /* we'll need to create a new record */
1159
1160                 size = sizeof(*data) + sizeof(deferred_open_entry) + strlen(fname) + 1;
1161                 p = (char *)SMB_MALLOC(size);
1162                 if (!p)
1163                         return False;
1164                 data = (struct deferred_open_data *)p;
1165                 data->u.num_deferred_open_entries = 1;
1166         
1167                 DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n",
1168                         fname ));
1169
1170                 offset = sizeof(*data) + sizeof(deferred_open_entry);
1171                 safe_strcpy(p + offset, fname, size - offset - 1);
1172                 fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port);
1173                 dbuf.dptr = p;
1174                 dbuf.dsize = size;
1175                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
1176                         ret = False;
1177
1178                 print_deferred_open_table((struct deferred_open_data *)p);
1179
1180                 SAFE_FREE(p);
1181                 return ret;
1182         }
1183
1184         /* we're adding to an existing entry - this is a bit fiddly */
1185         data = (struct deferred_open_data *)dbuf.dptr;
1186
1187         data->u.num_deferred_open_entries++;
1188         
1189         DEBUG(10,("add_deferred_open: adding entry for file %s. new num_deferred_open_entries = %d\n",
1190                 fname, data->u.num_deferred_open_entries ));
1191
1192         size = dbuf.dsize + sizeof(deferred_open_entry);
1193         p = SMB_MALLOC(size);
1194         if (!p) {
1195                 SAFE_FREE(dbuf.dptr);
1196                 return False;
1197         }
1198         memcpy(p, dbuf.dptr, sizeof(*data));
1199         fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port);
1200         memcpy(p + sizeof(*data) + sizeof(deferred_open_entry), dbuf.dptr + sizeof(*data),
1201                dbuf.dsize - sizeof(*data));
1202         SAFE_FREE(dbuf.dptr);
1203         dbuf.dptr = p;
1204         dbuf.dsize = size;
1205         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
1206                 ret = False;
1207         print_deferred_open_table((struct deferred_open_data *)p);
1208         SAFE_FREE(p);
1209         return ret;
1210 }
1211
1212 /****************************************************************************
1213  Traverse the whole database with this function, calling traverse_callback
1214  on each share mode
1215 ****************************************************************************/
1216
1217 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, 
1218                        void* state)
1219 {
1220         struct locking_data *data;
1221         share_mode_entry *shares;
1222         char *name;
1223         int i;
1224
1225         SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state;
1226
1227         /* Ensure this is a locking_key record. */
1228         if (kbuf.dsize != sizeof(struct locking_key))
1229                 return 0;
1230
1231         data = (struct locking_data *)dbuf.dptr;
1232         shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
1233         name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares);
1234
1235         for (i=0;i<data->u.num_share_mode_entries;i++) {
1236                 traverse_callback(&shares[i], name);
1237         }
1238         return 0;
1239 }
1240
1241 /*******************************************************************
1242  Call the specified function on each entry under management by the
1243  share mode system.
1244 ********************************************************************/
1245
1246 int share_mode_forall(SHAREMODE_FN(fn))
1247 {
1248         if (!tdb)
1249                 return 0;
1250         return tdb_traverse(tdb, traverse_fn, (void*)fn);
1251 }