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