O_EXCL fixes for printing files & oplocks.
[samba.git] / source / smbd / oplock.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    oplock processing
5    Copyright (C) Andrew Tridgell 1992-1998
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
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 /* Oplock ipc UDP socket. */
27 static int oplock_sock = -1;
28 uint16 global_oplock_port = 0;
29 #if defined(HAVE_KERNEL_OPLOCKS)
30 static int oplock_pipe_read = -1;
31 static int oplock_pipe_write = -1;
32 #endif /* HAVE_KERNEL_OPLOCKS */
33
34 /* Current number of oplocks we have outstanding. */
35 int32 global_oplocks_open = 0;
36 BOOL global_oplock_break = False;
37
38 extern int smb_read_error;
39
40 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
41
42 /****************************************************************************
43   open the oplock IPC socket communication
44 ****************************************************************************/
45 BOOL open_oplock_ipc(void)
46 {
47   struct sockaddr_in sock_name;
48   int len = sizeof(sock_name);
49
50   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
51
52   /* Open a lookback UDP socket on a random port. */
53   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
54   if (oplock_sock == -1)
55   {
56     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
57 address %lx. Error was %s\n", (long)htonl(INADDR_LOOPBACK), strerror(errno)));
58     global_oplock_port = 0;
59     return(False);
60   }
61
62   /* Find out the transient UDP port we have been allocated. */
63   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
64   {
65     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
66             strerror(errno)));
67     close(oplock_sock);
68     oplock_sock = -1;
69     global_oplock_port = 0;
70     return False;
71   }
72   global_oplock_port = ntohs(sock_name.sin_port);
73
74   DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n", 
75             (int)getpid(), global_oplock_port));
76
77   return True;
78 }
79
80 /****************************************************************************
81  Read an oplock break message from the either the oplock UDP fd
82  or the kernel oplock pipe fd (if kernel oplocks are supported).
83
84  If timeout is zero then *fds contains the file descriptors that
85  are ready to be read and acted upon. If timeout is non-zero then
86  *fds contains the file descriptors to be selected on for read.
87  The timeout is in milliseconds
88
89 ****************************************************************************/
90
91 BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout)
92 {
93   struct sockaddr_in from;
94   int fromlen = sizeof(from);
95   int32 msg_len = 0;
96
97   smb_read_error = 0;
98
99   if(timeout != 0) {
100     struct timeval to;
101     int selrtn;
102     int maxfd = oplock_sock;
103
104 #if defined(HAVE_KERNEL_OPLOCKS)
105     if(lp_kernel_oplocks())
106       maxfd = MAX(maxfd, oplock_pipe_read);
107 #endif /* HAVE_KERNEL_OPLOCKS */
108
109     to.tv_sec = timeout / 1000;
110     to.tv_usec = (timeout % 1000) * 1000;
111
112     selrtn = sys_select(maxfd+1,fds,&to);
113
114     /* Check if error */
115     if(selrtn == -1) {
116       /* something is wrong. Maybe the socket is dead? */
117       smb_read_error = READ_ERROR;
118       return False;
119     }
120
121     /* Did we timeout ? */
122     if (selrtn == 0) {
123       smb_read_error = READ_TIMEOUT;
124       return False;
125     }
126   }
127
128 #if defined(HAVE_KERNEL_OPLOCKS)
129   if(FD_ISSET(oplock_pipe_read,fds)) {
130     /*
131      * Deal with the kernel <--> smbd
132      * oplock break protocol.
133      */
134
135     oplock_stat_t os;
136     SMB_DEV_T dev;
137     SMB_INO_T inode;
138     char dummy;
139
140     /*
141      * Read one byte of zero to clear the
142      * kernel break notify message.
143      */
144
145     if(read(oplock_pipe_read, &dummy, 1) != 1) {
146       DEBUG(0,("receive_local_message: read of kernel notification failed. \
147 Error was %s.\n", strerror(errno) ));
148       smb_read_error = READ_ERROR;
149       return False;
150     }
151
152     /*
153      * Do a query to get the
154      * device and inode of the file that has the break
155      * request outstanding.
156      */
157
158     if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
159       DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
160 Error was %s.\n", strerror(errno) ));
161       smb_read_error = READ_ERROR;
162       return False;
163     }
164
165     dev = (SMB_DEV_T)os.os_dev;
166     inode = (SMB_DEV_T)os.os_ino;
167
168     DEBUG(5,("receive_local_message: kernel oplock break request received for \
169 dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
170
171     /*
172      * Create a kernel oplock break message.
173      */
174
175     /* Setup the message header */
176     SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
177     SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
178
179     buffer += OPBRK_CMD_HEADER_LEN;
180
181     SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
182     SIVAL(buffer,KERNEL_OPLOCK_BREAK_DEV_OFFSET,dev);
183
184 #ifdef LARGE_SMB_INO_T
185     SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode & 0xFFFFFFFF);
186     SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET+4, (inode >> 32 ) & 0xFFFFFFFF );
187 #else /* LARGE_SMB_INO_T */
188     SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode);
189 #endif /* LARGE_SMB_INO_T */
190
191     return True;
192   }
193 #endif /* HAVE_KERNEL_OPLOCKS */
194
195   /*
196    * From here down we deal with the smbd <--> smbd
197    * oplock break protocol only.
198    */
199
200   /*
201    * Read a loopback udp message.
202    */
203   msg_len = recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
204                      buffer_len - OPBRK_CMD_HEADER_LEN, 0,
205                      (struct sockaddr *)&from, &fromlen);
206
207   if(msg_len < 0) {
208     DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
209     return False;
210   }
211
212   /* Validate message length. */
213   if(msg_len > (buffer_len - OPBRK_CMD_HEADER_LEN)) {
214     DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
215               msg_len,
216               buffer_len  - OPBRK_CMD_HEADER_LEN));
217     return False;
218   }
219
220   /* Validate message from address (must be localhost). */
221   if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
222     DEBUG(0,("receive_local_message: invalid 'from' address \
223 (was %lx should be 127.0.0.1\n", (long)from.sin_addr.s_addr));
224    return False;
225   }
226
227   /* Setup the message header */
228   SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,msg_len);
229   SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,ntohs(from.sin_port));
230
231   return True;
232 }
233
234 /****************************************************************************
235  Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
236  disabled (just sets flags). Returns True if oplock set.
237 ****************************************************************************/
238
239 BOOL set_file_oplock(files_struct *fsp)
240 {
241 #if defined(HAVE_KERNEL_OPLOCKS)
242   if(lp_kernel_oplocks()) {
243
244     if(fcntl(fsp->fd_ptr->fd, F_OPLKREG, oplock_pipe_write) < 0 ) {
245       if(errno != EAGAIN) {
246         DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
247 inode = %.0f. Error was %s\n", 
248               fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
249                strerror(errno) ));
250       } else {
251         DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
252 inode = %.0f. Another process had the file open.\n",
253               fsp->fsp_name, fsp->fd_ptr->fd, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode ));
254       }
255       return False;
256     }
257
258     DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
259           fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
260
261   }
262 #endif /* HAVE_KERNEL_OPLOCKS */
263
264   DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f\n", 
265         fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
266
267   fsp->granted_oplock = True;
268   fsp->sent_oplock_break = False;
269   global_oplocks_open++;
270
271   return True;
272 }
273
274 /****************************************************************************
275  Attempt to release an oplock on a file. Always succeeds if kernel oplocks are
276  disabled (just clears flags).
277 ****************************************************************************/
278
279 static void release_file_oplock(files_struct *fsp)
280 {
281 #if defined(HAVE_KERNEL_OPLOCKS)
282
283   if(lp_kernel_oplocks())
284   {
285     if( DEBUGLVL( 10 ))
286     {
287       /*
288        * Check and print out the current kernel
289        * oplock state of this file.
290        */
291       int state = fcntl(fsp->fd_ptr->fd, F_OPLKACK, -1);
292       dbgtext("release_file_oplock: file %s, dev = %x, inode = %.0f has kernel \
293 oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
294                         (double)fsp->fd_ptr->inode, state );
295     }
296
297     /*
298      * Remote the kernel oplock on this file.
299      */
300
301     if(fcntl(fsp->fd_ptr->fd, F_OPLKACK, OP_REVOKE) < 0)
302     {
303       if( DEBUGLVL( 0 ))
304       {
305         dbgtext("release_file_oplock: Error when removing kernel oplock on file " );
306         dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
307                  fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, 
308                  (double)fsp->fd_ptr->inode, strerror(errno) );
309       }
310     }
311   }
312 #endif /* HAVE_KERNEL_OPLOCKS */
313
314   fsp->granted_oplock = False;
315   fsp->sent_oplock_break = False;
316   global_oplocks_open--;
317 }
318
319 /****************************************************************************
320  Setup the listening set of file descriptors for an oplock break
321  message either from the UDP socket or from the kernel. Returns the maximum
322  fd used.
323 ****************************************************************************/
324
325 int setup_oplock_select_set( fd_set *fds)
326 {
327   int maxfd = oplock_sock;
328   FD_SET(oplock_sock,fds);
329
330 #if defined(HAVE_KERNEL_OPLOCKS)
331   if(lp_kernel_oplocks()) {
332     FD_SET(oplock_pipe_read,fds); 
333     maxfd = MAX(maxfd,oplock_pipe_read);
334   }
335 #endif /* HAVE_KERNEL_OPLOCKS */
336
337   return maxfd;
338 }
339
340 /****************************************************************************
341  Process an oplock break message - whether it came from the UDP socket
342  or from the kernel.
343 ****************************************************************************/
344
345 BOOL process_local_message(char *buffer, int buf_size)
346 {
347   int32 msg_len;
348   uint16 from_port;
349   char *msg_start;
350   SMB_DEV_T dev;
351   SMB_INO_T inode;
352   uint32 remotepid;
353   struct timeval tval;
354   struct timeval *ptval = NULL;
355
356   msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
357   from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
358
359   msg_start = &buffer[OPBRK_CMD_HEADER_LEN];
360
361   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
362             msg_len, from_port));
363
364   /* 
365    * Pull the info out of the requesting packet.
366    */
367
368   switch(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET))
369   {
370 #if defined(HAVE_KERNEL_OPLOCKS)
371     case KERNEL_OPLOCK_BREAK_CMD:
372       /* Ensure that the msg length is correct. */
373       if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN)
374       {
375         DEBUG(0,("process_local_message: incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, \
376 should be %d).\n", msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
377         return False;
378       }
379       {
380         /*
381          * Warning - beware of SMB_INO_T <> 4 bytes. !!
382          */
383 #ifdef LARGE_SMB_INO_T
384         SMB_INO_T inode_low = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
385         SMB_INO_T inode_high = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET + 4);
386         inode = inode_low | (inode_high << 32);
387 #else /* LARGE_SMB_INO_T */
388         inode = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
389 #endif /* LARGE_SMB_INO_T */
390
391         dev = IVAL(msg_start,KERNEL_OPLOCK_BREAK_DEV_OFFSET);
392
393         ptval = NULL;
394
395         DEBUG(5,("process_local_message: kernel oplock break request for \
396 file dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode));
397       }
398       break;
399 #endif /* HAVE_KERNEL_OPLOCKS */
400
401     case OPLOCK_BREAK_CMD:
402       /* Ensure that the msg length is correct. */
403       if(msg_len != OPLOCK_BREAK_MSG_LEN)
404       {
405         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
406 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
407         return False;
408       }
409       {
410         /*
411          * Warning - beware of SMB_INO_T <> 4 bytes. !!
412          */
413 #ifdef LARGE_SMB_INO_T
414         SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
415         SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
416         inode = inode_low | (inode_high << 32);
417 #else /* LARGE_SMB_INO_T */
418         inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
419 #endif /* LARGE_SMB_INO_T */
420
421         dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
422
423         tval.tv_sec = (time_t)IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
424         tval.tv_usec = (long)IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
425
426         ptval = &tval;
427
428         remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
429
430         DEBUG(5,("process_local_message: oplock break request from \
431 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
432       }
433       break;
434
435     /* 
436      * Keep this as a debug case - eventually we can remove it.
437      */
438     case 0x8001:
439       DEBUG(0,("process_local_message: Received unsolicited break \
440 reply - dumping info.\n"));
441
442       if(msg_len != OPLOCK_BREAK_MSG_LEN)
443       {
444         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
445 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
446         return False;
447       }
448
449       {
450         /*
451          * Warning - beware of SMB_INO_T <> 4 bytes. !!
452          */
453 #ifdef LARGE_SMB_INO_T
454         SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
455         SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
456         inode = inode_low | (inode_high << 32);
457 #else /* LARGE_SMB_INO_T */
458         inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
459 #endif /* LARGE_SMB_INO_T */
460
461         remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
462         dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
463
464         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
465 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
466
467        }
468        return False;
469
470     default:
471       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
472                 (unsigned int)SVAL(msg_start,0)));
473       return False;
474   }
475
476   /*
477    * Now actually process the break request.
478    */
479
480   if(global_oplocks_open != 0)
481   {
482     if(oplock_break(dev, inode, ptval) == False)
483     {
484       DEBUG(0,("process_local_message: oplock break failed.\n"));
485       return False;
486     }
487   }
488   else
489   {
490     /*
491      * If we have no record of any currently open oplocks,
492      * it's not an error, as a close command may have
493      * just been issued on the file that was oplocked.
494      * Just log a message and return success in this case.
495      */
496     DEBUG(3,("process_local_message: oplock break requested with no outstanding \
497 oplocks. Returning success.\n"));
498   }
499
500   /* 
501    * Do the appropriate reply - none in the kernel case.
502    */
503
504   if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD)
505   {
506     struct sockaddr_in toaddr;
507
508     /* Send the message back after OR'ing in the 'REPLY' bit. */
509     SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
510
511     bzero((char *)&toaddr,sizeof(toaddr));
512     toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
513     toaddr.sin_port = htons(from_port);
514     toaddr.sin_family = AF_INET;
515
516     if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
517             (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
518     {
519       DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
520                 remotepid, strerror(errno)));
521       return False;
522     }
523
524     DEBUG(5,("process_local_message: oplock break reply sent to \
525 pid %d, port %d, for file dev = %x, inode = %.0f\n",
526           remotepid, from_port, (unsigned int)dev, (double)inode));
527   }
528
529   return True;
530 }
531
532 /****************************************************************************
533  Process an oplock break directly.
534 ****************************************************************************/
535
536 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
537 {
538   extern struct current_user current_user;
539   extern int Client;
540   char *inbuf = NULL;
541   char *outbuf = NULL;
542   files_struct *fsp = NULL;
543   time_t start_time;
544   BOOL shutdown_server = False;
545   connection_struct *saved_conn;
546   int saved_vuid;
547   pstring saved_dir; 
548   int break_counter = OPLOCK_BREAK_RESENDS;
549
550   if( DEBUGLVL( 3 ) )
551   {
552     dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
553     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
554   }
555
556   /* We need to search the file open table for the
557      entry containing this dev and inode, and ensure
558      we have an oplock on it. */
559   fsp = file_find_dit(dev, inode, tval);
560
561   if(fsp == NULL)
562   {
563     /* The file could have been closed in the meantime - return success. */
564     if( DEBUGLVL( 0 ) )
565     {
566       dbgtext( "oplock_break: cannot find open file with " );
567       dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
568       dbgtext( "allowing break to succeed.\n" );
569     }
570     return True;
571   }
572
573   /* Ensure we have an oplock on the file */
574
575   /* There is a potential race condition in that an oplock could
576      have been broken due to another udp request, and yet there are
577      still oplock break messages being sent in the udp message
578      queue for this file. So return true if we don't have an oplock,
579      as we may have just freed it.
580    */
581
582   if(!fsp->granted_oplock)
583   {
584     if( DEBUGLVL( 0 ) )
585     {
586       dbgtext( "oplock_break: file %s ", fsp->fsp_name );
587       dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
588       dbgtext( "Allowing break to succeed regardless.\n" );
589     }
590     return True;
591   }
592
593   /* mark the oplock break as sent - we don't want to send twice! */
594   if (fsp->sent_oplock_break)
595   {
596     if( DEBUGLVL( 0 ) )
597     {
598       dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
599       dbgtext( "file %s ", fsp->fsp_name);
600       dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev, (double)inode );
601     }
602
603     /* We have to fail the open here as we cannot send another oplock break on
604        this file whilst we are awaiting a response from the client - neither
605        can we allow another open to succeed while we are waiting for the
606        client.
607      */
608     return False;
609   }
610
611   /* Now comes the horrid part. We must send an oplock break to the client,
612      and then process incoming messages until we get a close or oplock release.
613      At this point we know we need a new inbuf/outbuf buffer pair.
614      We cannot use these staticaly as we may recurse into here due to
615      messages crossing on the wire.
616    */
617
618   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
619   {
620     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
621     return False;
622   }
623
624   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
625   {
626     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
627     free(inbuf);
628     inbuf = NULL;
629     return False;
630   }
631
632   /* Prepare the SMBlockingX message. */
633   bzero(outbuf,smb_size);
634   set_message(outbuf,8,0,True);
635
636   SCVAL(outbuf,smb_com,SMBlockingX);
637   SSVAL(outbuf,smb_tid,fsp->conn->cnum);
638   SSVAL(outbuf,smb_pid,0xFFFF);
639   SSVAL(outbuf,smb_uid,0);
640   SSVAL(outbuf,smb_mid,0xFFFF);
641   SCVAL(outbuf,smb_vwv0,0xFF);
642   SSVAL(outbuf,smb_vwv2,fsp->fnum);
643   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
644   /* Change this when we have level II oplocks. */
645   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
646  
647   send_smb(Client, outbuf);
648
649   /* Remember we just sent an oplock break on this file. */
650   fsp->sent_oplock_break = True;
651
652   /* We need this in case a readraw crosses on the wire. */
653   global_oplock_break = True;
654  
655   /* Process incoming messages. */
656
657   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
658      seconds we should just die.... */
659
660   start_time = time(NULL);
661
662   /*
663    * Save the information we need to re-become the
664    * user, then unbecome the user whilst we're doing this.
665    */
666   saved_conn = fsp->conn;
667   saved_vuid = current_user.vuid;
668   GetWd(saved_dir);
669   unbecome_user();
670   /* Save the chain fnum. */
671   file_chain_save();
672
673   while(OPEN_FSP(fsp) && fsp->granted_oplock)
674   {
675     if(receive_smb(Client,inbuf,
676                    (OPLOCK_BREAK_TIMEOUT/OPLOCK_BREAK_RESENDS) * 1000) == False)
677     {
678
679             /* Isaac suggestd that if a MS client doesn't respond to a
680                oplock break request then we might try resending
681                it. Certainly it's no worse than just dropping the
682                socket! */
683             if (smb_read_error == READ_TIMEOUT && break_counter--) {
684                     DEBUG(2, ( "oplock_break resend\n" ) );
685                     send_smb(Client, outbuf);
686                     continue;
687             }
688
689       /*
690        * Die if we got an error.
691        */
692
693       if (smb_read_error == READ_EOF)
694         DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
695  
696       if (smb_read_error == READ_ERROR)
697         DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
698
699       if (smb_read_error == READ_TIMEOUT)
700         DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
701                      OPLOCK_BREAK_TIMEOUT ) );
702
703       DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
704       DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
705
706       shutdown_server = True;
707       break;
708     }
709
710     /*
711      * There are certain SMB requests that we shouldn't allow
712      * to recurse. opens, renames and deletes are the obvious
713      * ones. This is handled in the switch_message() function.
714      * If global_oplock_break is set they will push the packet onto
715      * the pending smb queue and return -1 (no reply).
716      * JRA.
717      */
718
719     process_smb(inbuf, outbuf);
720
721     /*
722      * Die if we go over the time limit.
723      */
724
725     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
726     {
727       if( DEBUGLVL( 0 ) )
728         {
729         dbgtext( "oplock_break: no break received from client " );
730         dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
731         dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
732         dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
733         }
734       shutdown_server = True;
735       break;
736     }
737   }
738
739   /*
740    * Go back to being the user who requested the oplock
741    * break.
742    */
743   if(!become_user(saved_conn, saved_vuid))
744   {
745     DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
746     DEBUGADD( 0, ( "Shutting down server\n" ) );
747     close_sockets();
748     close(oplock_sock);
749     exit_server("unable to re-become user");
750   }
751   /* Including the directory. */
752   ChDir(saved_dir);
753
754   /* Restore the chain fnum. */
755   file_chain_restore();
756
757   /* Free the buffers we've been using to recurse. */
758   free(inbuf);
759   free(outbuf);
760
761   /* We need this in case a readraw crossed on the wire. */
762   if(global_oplock_break)
763     global_oplock_break = False;
764
765   /*
766    * If the client did not respond we must die.
767    */
768
769   if(shutdown_server)
770   {
771     DEBUG( 0, ( "oplock_break: client failure in break - " ) );
772     DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
773     close_sockets();
774     close(oplock_sock);
775     exit_server("oplock break failure");
776   }
777
778   if(OPEN_FSP(fsp))
779   {
780     /* The lockingX reply will have removed the oplock flag 
781        from the sharemode. */
782     release_file_oplock(fsp);
783   }
784
785   /* Santity check - remove this later. JRA */
786   if(global_oplocks_open < 0)
787   {
788     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
789               global_oplocks_open));
790     exit_server("oplock_break: global_oplocks_open < 0");
791   }
792
793
794   if( DEBUGLVL( 3 ) )
795   {
796     dbgtext( "oplock_break: returning success for " );
797     dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
798     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
799   }
800
801   return True;
802 }
803
804 /****************************************************************************
805 Send an oplock break message to another smbd process. If the oplock is held 
806 by the local smbd then call the oplock break function directly.
807 ****************************************************************************/
808
809 BOOL request_oplock_break(share_mode_entry *share_entry, 
810                           SMB_DEV_T dev, SMB_INO_T inode)
811 {
812   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
813   struct sockaddr_in addr_out;
814   int pid = getpid();
815   time_t start_time;
816   int time_left;
817
818   if(pid == share_entry->pid)
819   {
820     /* We are breaking our own oplock, make sure it's us. */
821     if(share_entry->op_port != global_oplock_port)
822     {
823       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
824 should be %d\n", pid, share_entry->op_port, global_oplock_port));
825       return False;
826     }
827
828     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
829
830     /* Call oplock break direct. */
831     return oplock_break(dev, inode, &share_entry->time);
832   }
833
834   /* We need to send a OPLOCK_BREAK_CMD message to the
835      port in the share mode entry. */
836
837   SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
838   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
839   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
840   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
841   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
842   /*
843    * WARNING - beware of SMB_INO_T <> 4 bytes.
844    */
845 #ifdef LARGE_SMB_INO_T
846   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
847   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
848 #else /* LARGE_SMB_INO_T */
849   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
850 #endif /* LARGE_SMB_INO_T */
851
852   /* set the address and port */
853   bzero((char *)&addr_out,sizeof(addr_out));
854   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
855   addr_out.sin_port = htons( share_entry->op_port );
856   addr_out.sin_family = AF_INET;
857    
858   if( DEBUGLVL( 3 ) )
859   {
860     dbgtext( "request_oplock_break: sending a oplock break message to " );
861     dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
862     dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
863   }
864
865   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
866          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
867   {
868     if( DEBUGLVL( 0 ) )
869     {
870       dbgtext( "request_oplock_break: failed when sending a oplock " );
871       dbgtext( "break message to pid %d ", share_entry->pid );
872       dbgtext( "on port %d ", share_entry->op_port );
873       dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
874       dbgtext( "Error was %s\n", strerror(errno) );
875     }
876     return False;
877   }
878
879   /*
880    * Now we must await the oplock broken message coming back
881    * from the target smbd process. Timeout if it fails to
882    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
883    * While we get messages that aren't ours, loop.
884    */
885
886   start_time = time(NULL);
887   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
888
889   while(time_left >= 0)
890   {
891     char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
892     int32 reply_msg_len;
893     uint16 reply_from_port;
894     char *reply_msg_start;
895     fd_set fds;
896
897     FD_ZERO(&fds);
898     FD_SET(oplock_sock,&fds);
899 #if defined(HAVE_KERNEL_OPLOCKS)
900     if(lp_kernel_oplocks())
901       FD_SET(oplock_pipe_read,&fds);
902 #endif /* HAVE_KERNEL_OPLOCKS */
903
904     if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
905                time_left ? time_left * 1000 : 1) == False)
906     {
907       if(smb_read_error == READ_TIMEOUT)
908       {
909         if( DEBUGLVL( 0 ) )
910         {
911           dbgtext( "request_oplock_break: no response received to oplock " );
912           dbgtext( "break request to pid %d ", share_entry->pid );
913           dbgtext( "on port %d ", share_entry->op_port );
914           dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
915         }
916
917         /*
918          * This is a hack to make handling of failing clients more robust.
919          * If a oplock break response message is not received in the timeout
920          * period we may assume that the smbd servicing that client holding
921          * the oplock has died and the client changes were lost anyway, so
922          * we should continue to try and open the file.
923          */
924         break;
925       }
926       else
927         if( DEBUGLVL( 0 ) )
928         {
929           dbgtext( "request_oplock_break: error in response received " );
930           dbgtext( "to oplock break request to pid %d ", share_entry->pid );
931           dbgtext( "on port %d ", share_entry->op_port );
932           dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
933           dbgtext( "Error was (%s).\n", strerror(errno) );
934         }
935       return False;
936     }
937
938     reply_msg_len = IVAL(op_break_reply,OPBRK_CMD_LEN_OFFSET);
939     reply_from_port = SVAL(op_break_reply,OPBRK_CMD_PORT_OFFSET);
940
941     reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
942
943
944 #if defined(HAVE_KERNEL_OPLOCKS)
945     if((reply_msg_len != OPLOCK_BREAK_MSG_LEN) && (reply_msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN))
946 #else
947     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
948 #endif
949     {
950       /* Ignore it. */
951       DEBUG( 0, ( "request_oplock_break: invalid message length (%d) received.", reply_msg_len ) );
952       DEBUGADD( 0, ( "  Ignoring.\n" ) );
953       continue;
954     }
955
956     /*
957      * Test to see if this is the reply we are awaiting.
958      */
959
960     if((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
961        ((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & ~CMD_REPLY) == OPLOCK_BREAK_CMD) &&
962        (reply_from_port == share_entry->op_port) && 
963        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
964                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
965                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
966     {
967       /*
968        * This is the reply we've been waiting for.
969        */
970       break;
971     }
972     else
973     {
974       /*
975        * This is another message - a break request.
976        * Note that both kernel oplock break requests
977        * and UDP inter-smbd oplock break requests will
978        * be processed here.
979        *
980        * Process it to prevent potential deadlock.
981        * Note that the code in switch_message() prevents
982        * us from recursing into here as any SMB requests
983        * we might process that would cause another oplock
984        * break request to be made will be queued.
985        * JRA.
986        */
987
988       process_local_message(op_break_reply, sizeof(op_break_reply));
989     }
990
991     time_left -= (time(NULL) - start_time);
992   }
993
994   DEBUG(3,("request_oplock_break: broke oplock.\n"));
995
996   return True;
997 }
998
999 /****************************************************************************
1000   Attempt to break an oplock on a file (if oplocked).
1001   Returns True if the file was closed as a result of
1002   the oplock break, False otherwise.
1003   Used as a last ditch attempt to free a space in the 
1004   file table when we have run out.
1005 ****************************************************************************/
1006 BOOL attempt_close_oplocked_file(files_struct *fsp)
1007 {
1008
1009   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
1010
1011   if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
1012
1013     /* Try and break the oplock. */
1014     file_fd_struct *fd_ptr = fsp->fd_ptr;
1015     if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
1016       if(!fsp->open) /* Did the oplock break close the file ? */
1017         return True;
1018     }
1019   }
1020
1021   return False;
1022 }
1023
1024 /****************************************************************************
1025  Init function to check if kernel level oplocks are available.
1026 ****************************************************************************/
1027
1028 void check_kernel_oplocks(void)
1029 {
1030   static BOOL done;
1031
1032   /*
1033    * We only do this check once on startup.
1034    */
1035
1036   if(done)
1037     return;
1038
1039   done = True;
1040   lp_set_kernel_oplocks(False);
1041
1042 #if defined(HAVE_KERNEL_OPLOCKS)
1043   {
1044     int fd;
1045     int pfd[2];
1046     pstring tmpname;
1047
1048     set_process_capability(KERNEL_OPLOCK_CAPABILITY,True);
1049     set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,True);
1050
1051     slprintf( tmpname, sizeof(tmpname)-1, "/tmp/ot.%d.XXXXXX", (unsigned int)getpid());
1052     mktemp(tmpname);
1053
1054     if(pipe(pfd) != 0) {
1055       DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error was %s\n",
1056             strerror(errno) ));
1057       return;
1058     }
1059
1060     if((fd = open(tmpname, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600)) < 0) {
1061       DEBUG(0,("check_kernel_oplocks: Unable to open temp test file %s. Error was %s\n",
1062             tmpname, strerror(errno) ));
1063       unlink( tmpname );
1064       close(pfd[0]);
1065       close(pfd[1]);
1066       return;
1067     }
1068
1069     unlink( tmpname );
1070
1071     if(fcntl(fd, F_OPLKREG, pfd[1]) == -1) {
1072       DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not available on this machine. \
1073 Disabling kernel oplock support.\n" ));
1074       close(pfd[0]);
1075       close(pfd[1]);
1076       close(fd);
1077       return;
1078     }
1079
1080     if(fcntl(fd, F_OPLKACK, OP_REVOKE) < 0 ) {
1081       DEBUG(0,("check_kernel_oplocks: Error when removing kernel oplock. Error was %s. \
1082 Disabling kernel oplock support.\n", strerror(errno) ));
1083       close(pfd[0]);
1084       close(pfd[1]);
1085       close(fd);
1086       return;
1087     }
1088
1089     oplock_pipe_read = pfd[0];
1090     oplock_pipe_write = pfd[1];
1091     close(fd);
1092
1093     lp_set_kernel_oplocks(True);
1094
1095     DEBUG(3,("check_kernel_oplocks: Kernel oplocks available and set to %s.\n",
1096           lp_kernel_oplocks() ? "True" : "False" ));
1097
1098   }
1099 #endif /* HAVE_KERNEL_OPLOCKS */
1100 }