more warnings...
[tprouty/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", 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 %x should be 127.0.0.1\n", 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
549   if( DEBUGLVL( 3 ) )
550   {
551     dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
552     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
553   }
554
555   /* We need to search the file open table for the
556      entry containing this dev and inode, and ensure
557      we have an oplock on it. */
558   fsp = file_find_dit(dev, inode, tval);
559
560   if(fsp == NULL)
561   {
562     /* The file could have been closed in the meantime - return success. */
563     if( DEBUGLVL( 0 ) )
564     {
565       dbgtext( "oplock_break: cannot find open file with " );
566       dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
567       dbgtext( "allowing break to succeed.\n" );
568     }
569     return True;
570   }
571
572   /* Ensure we have an oplock on the file */
573
574   /* There is a potential race condition in that an oplock could
575      have been broken due to another udp request, and yet there are
576      still oplock break messages being sent in the udp message
577      queue for this file. So return true if we don't have an oplock,
578      as we may have just freed it.
579    */
580
581   if(!fsp->granted_oplock)
582   {
583     if( DEBUGLVL( 0 ) )
584     {
585       dbgtext( "oplock_break: file %s ", fsp->fsp_name );
586       dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
587       dbgtext( "Allowing break to succeed regardless.\n" );
588     }
589     return True;
590   }
591
592   /* mark the oplock break as sent - we don't want to send twice! */
593   if (fsp->sent_oplock_break)
594   {
595     if( DEBUGLVL( 0 ) )
596     {
597       dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
598       dbgtext( "file %s ", fsp->fsp_name);
599       dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev, (double)inode );
600     }
601
602     /* We have to fail the open here as we cannot send another oplock break on
603        this file whilst we are awaiting a response from the client - neither
604        can we allow another open to succeed while we are waiting for the
605        client.
606      */
607     return False;
608   }
609
610   /* Now comes the horrid part. We must send an oplock break to the client,
611      and then process incoming messages until we get a close or oplock release.
612      At this point we know we need a new inbuf/outbuf buffer pair.
613      We cannot use these staticaly as we may recurse into here due to
614      messages crossing on the wire.
615    */
616
617   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
618   {
619     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
620     return False;
621   }
622
623   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
624   {
625     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
626     free(inbuf);
627     inbuf = NULL;
628     return False;
629   }
630
631   /* Prepare the SMBlockingX message. */
632   bzero(outbuf,smb_size);
633   set_message(outbuf,8,0,True);
634
635   SCVAL(outbuf,smb_com,SMBlockingX);
636   SSVAL(outbuf,smb_tid,fsp->conn->cnum);
637   SSVAL(outbuf,smb_pid,0xFFFF);
638   SSVAL(outbuf,smb_uid,0);
639   SSVAL(outbuf,smb_mid,0xFFFF);
640   SCVAL(outbuf,smb_vwv0,0xFF);
641   SSVAL(outbuf,smb_vwv2,fsp->fnum);
642   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
643   /* Change this when we have level II oplocks. */
644   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
645  
646   send_smb(Client, outbuf);
647
648   /* Remember we just sent an oplock break on this file. */
649   fsp->sent_oplock_break = True;
650
651   /* We need this in case a readraw crosses on the wire. */
652   global_oplock_break = True;
653  
654   /* Process incoming messages. */
655
656   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
657      seconds we should just die.... */
658
659   start_time = time(NULL);
660
661   /*
662    * Save the information we need to re-become the
663    * user, then unbecome the user whilst we're doing this.
664    */
665   saved_conn = fsp->conn;
666   saved_vuid = current_user.vuid;
667   GetWd(saved_dir);
668   unbecome_user();
669   /* Save the chain fnum. */
670   file_chain_save();
671
672   while(OPEN_FSP(fsp) && fsp->granted_oplock)
673   {
674     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
675     {
676       /*
677        * Die if we got an error.
678        */
679
680       if (smb_read_error == READ_EOF)
681         DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
682  
683       if (smb_read_error == READ_ERROR)
684         DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
685
686       if (smb_read_error == READ_TIMEOUT)
687         DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
688                      OPLOCK_BREAK_TIMEOUT ) );
689
690       DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
691       DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
692
693       shutdown_server = True;
694       break;
695     }
696
697     /*
698      * There are certain SMB requests that we shouldn't allow
699      * to recurse. opens, renames and deletes are the obvious
700      * ones. This is handled in the switch_message() function.
701      * If global_oplock_break is set they will push the packet onto
702      * the pending smb queue and return -1 (no reply).
703      * JRA.
704      */
705
706     process_smb(inbuf, outbuf);
707
708     /*
709      * Die if we go over the time limit.
710      */
711
712     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
713     {
714       if( DEBUGLVL( 0 ) )
715         {
716         dbgtext( "oplock_break: no break received from client " );
717         dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
718         dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
719         dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
720         }
721       shutdown_server = True;
722       break;
723     }
724   }
725
726   /*
727    * Go back to being the user who requested the oplock
728    * break.
729    */
730   if(!become_user(saved_conn, saved_vuid))
731   {
732     DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
733     DEBUGADD( 0, ( "Shutting down server\n" ) );
734     close_sockets();
735     close(oplock_sock);
736     exit_server("unable to re-become user");
737   }
738   /* Including the directory. */
739   ChDir(saved_dir);
740
741   /* Restore the chain fnum. */
742   file_chain_restore();
743
744   /* Free the buffers we've been using to recurse. */
745   free(inbuf);
746   free(outbuf);
747
748   /* We need this in case a readraw crossed on the wire. */
749   if(global_oplock_break)
750     global_oplock_break = False;
751
752   /*
753    * If the client did not respond we must die.
754    */
755
756   if(shutdown_server)
757   {
758     DEBUG( 0, ( "oplock_break: client failure in break - " ) );
759     DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
760     close_sockets();
761     close(oplock_sock);
762     exit_server("oplock break failure");
763   }
764
765   if(OPEN_FSP(fsp))
766   {
767     /* The lockingX reply will have removed the oplock flag 
768        from the sharemode. */
769     release_file_oplock(fsp);
770   }
771
772   /* Santity check - remove this later. JRA */
773   if(global_oplocks_open < 0)
774   {
775     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
776               global_oplocks_open));
777     exit_server("oplock_break: global_oplocks_open < 0");
778   }
779
780
781   if( DEBUGLVL( 3 ) )
782   {
783     dbgtext( "oplock_break: returning success for " );
784     dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
785     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
786   }
787
788   return True;
789 }
790
791 /****************************************************************************
792 Send an oplock break message to another smbd process. If the oplock is held 
793 by the local smbd then call the oplock break function directly.
794 ****************************************************************************/
795
796 BOOL request_oplock_break(share_mode_entry *share_entry, 
797                           SMB_DEV_T dev, SMB_INO_T inode)
798 {
799   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
800   struct sockaddr_in addr_out;
801   int pid = getpid();
802   time_t start_time;
803   int time_left;
804
805   if(pid == share_entry->pid)
806   {
807     /* We are breaking our own oplock, make sure it's us. */
808     if(share_entry->op_port != global_oplock_port)
809     {
810       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
811 should be %d\n", pid, share_entry->op_port, global_oplock_port));
812       return False;
813     }
814
815     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
816
817     /* Call oplock break direct. */
818     return oplock_break(dev, inode, &share_entry->time);
819   }
820
821   /* We need to send a OPLOCK_BREAK_CMD message to the
822      port in the share mode entry. */
823
824   SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
825   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
826   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
827   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
828   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
829   /*
830    * WARNING - beware of SMB_INO_T <> 4 bytes.
831    */
832 #ifdef LARGE_SMB_INO_T
833   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
834   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
835 #else /* LARGE_SMB_INO_T */
836   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
837 #endif /* LARGE_SMB_INO_T */
838
839   /* set the address and port */
840   bzero((char *)&addr_out,sizeof(addr_out));
841   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
842   addr_out.sin_port = htons( share_entry->op_port );
843   addr_out.sin_family = AF_INET;
844    
845   if( DEBUGLVL( 3 ) )
846   {
847     dbgtext( "request_oplock_break: sending a oplock break message to " );
848     dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
849     dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
850   }
851
852   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
853          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
854   {
855     if( DEBUGLVL( 0 ) )
856     {
857       dbgtext( "request_oplock_break: failed when sending a oplock " );
858       dbgtext( "break message to pid %d ", share_entry->pid );
859       dbgtext( "on port %d ", share_entry->op_port );
860       dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
861       dbgtext( "Error was %s\n", strerror(errno) );
862     }
863     return False;
864   }
865
866   /*
867    * Now we must await the oplock broken message coming back
868    * from the target smbd process. Timeout if it fails to
869    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
870    * While we get messages that aren't ours, loop.
871    */
872
873   start_time = time(NULL);
874   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
875
876   while(time_left >= 0)
877   {
878     char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
879     int32 reply_msg_len;
880     uint16 reply_from_port;
881     char *reply_msg_start;
882     fd_set fds;
883
884     FD_ZERO(&fds);
885     FD_SET(oplock_sock,&fds);
886 #if defined(HAVE_KERNEL_OPLOCKS)
887     if(lp_kernel_oplocks())
888       FD_SET(oplock_pipe_read,&fds);
889 #endif /* HAVE_KERNEL_OPLOCKS */
890
891     if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
892                time_left ? time_left * 1000 : 1) == False)
893     {
894       if(smb_read_error == READ_TIMEOUT)
895       {
896         if( DEBUGLVL( 0 ) )
897         {
898           dbgtext( "request_oplock_break: no response received to oplock " );
899           dbgtext( "break request to pid %d ", share_entry->pid );
900           dbgtext( "on port %d ", share_entry->op_port );
901           dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
902         }
903
904         /*
905          * This is a hack to make handling of failing clients more robust.
906          * If a oplock break response message is not received in the timeout
907          * period we may assume that the smbd servicing that client holding
908          * the oplock has died and the client changes were lost anyway, so
909          * we should continue to try and open the file.
910          */
911         break;
912       }
913       else
914         if( DEBUGLVL( 0 ) )
915         {
916           dbgtext( "request_oplock_break: error in response received " );
917           dbgtext( "to oplock break request to pid %d ", share_entry->pid );
918           dbgtext( "on port %d ", share_entry->op_port );
919           dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
920           dbgtext( "Error was (%s).\n", strerror(errno) );
921         }
922       return False;
923     }
924
925     reply_msg_len = IVAL(op_break_reply,OPBRK_CMD_LEN_OFFSET);
926     reply_from_port = SVAL(op_break_reply,OPBRK_CMD_PORT_OFFSET);
927
928     reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
929
930
931 #if defined(HAVE_KERNEL_OPLOCKS)
932     if((reply_msg_len != OPLOCK_BREAK_MSG_LEN) && (reply_msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN))
933 #else
934     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
935 #endif
936     {
937       /* Ignore it. */
938       DEBUG( 0, ( "request_oplock_break: invalid message length (%d) received.", reply_msg_len ) );
939       DEBUGADD( 0, ( "  Ignoring.\n" ) );
940       continue;
941     }
942
943     /*
944      * Test to see if this is the reply we are awaiting.
945      */
946
947     if((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
948        ((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & ~CMD_REPLY) == OPLOCK_BREAK_CMD) &&
949        (reply_from_port == share_entry->op_port) && 
950        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
951                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
952                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
953     {
954       /*
955        * This is the reply we've been waiting for.
956        */
957       break;
958     }
959     else
960     {
961       /*
962        * This is another message - a break request.
963        * Note that both kernel oplock break requests
964        * and UDP inter-smbd oplock break requests will
965        * be processed here.
966        *
967        * Process it to prevent potential deadlock.
968        * Note that the code in switch_message() prevents
969        * us from recursing into here as any SMB requests
970        * we might process that would cause another oplock
971        * break request to be made will be queued.
972        * JRA.
973        */
974
975       process_local_message(op_break_reply, sizeof(op_break_reply));
976     }
977
978     time_left -= (time(NULL) - start_time);
979   }
980
981   DEBUG(3,("request_oplock_break: broke oplock.\n"));
982
983   return True;
984 }
985
986 /****************************************************************************
987   Attempt to break an oplock on a file (if oplocked).
988   Returns True if the file was closed as a result of
989   the oplock break, False otherwise.
990   Used as a last ditch attempt to free a space in the 
991   file table when we have run out.
992 ****************************************************************************/
993 BOOL attempt_close_oplocked_file(files_struct *fsp)
994 {
995
996   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
997
998   if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
999
1000     /* Try and break the oplock. */
1001     file_fd_struct *fd_ptr = fsp->fd_ptr;
1002     if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
1003       if(!fsp->open) /* Did the oplock break close the file ? */
1004         return True;
1005     }
1006   }
1007
1008   return False;
1009 }
1010
1011 /****************************************************************************
1012  Init function to check if kernel level oplocks are available.
1013 ****************************************************************************/
1014
1015 void check_kernel_oplocks(void)
1016 {
1017   static BOOL done;
1018
1019   /*
1020    * We only do this check once on startup.
1021    */
1022
1023   if(done)
1024     return;
1025
1026   done = True;
1027   lp_set_kernel_oplocks(False);
1028
1029 #if defined(HAVE_KERNEL_OPLOCKS)
1030   {
1031     int fd;
1032     int pfd[2];
1033     pstring tmpname;
1034
1035     set_process_capability(KERNEL_OPLOCK_CAPABILITY,True);
1036     set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,True);
1037
1038     slprintf( tmpname, sizeof(tmpname)-1, "/tmp/ot.%d.XXXXXX", (unsigned int)getpid());
1039     mktemp(tmpname);
1040
1041     if(pipe(pfd) != 0) {
1042       DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error was %s\n",
1043             strerror(errno) ));
1044       return;
1045     }
1046
1047     if((fd = open(tmpname, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) {
1048       DEBUG(0,("check_kernel_oplocks: Unable to open temp test file %s. Error was %s\n",
1049             tmpname, strerror(errno) ));
1050       unlink( tmpname );
1051       close(pfd[0]);
1052       close(pfd[1]);
1053       return;
1054     }
1055
1056     unlink( tmpname );
1057
1058     if(fcntl(fd, F_OPLKREG, pfd[1]) == -1) {
1059       DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not available on this machine. \
1060 Disabling kernel oplock support.\n" ));
1061       close(pfd[0]);
1062       close(pfd[1]);
1063       close(fd);
1064       return;
1065     }
1066
1067     if(fcntl(fd, F_OPLKACK, OP_REVOKE) < 0 ) {
1068       DEBUG(0,("check_kernel_oplocks: Error when removing kernel oplock. Error was %s. \
1069 Disabling kernel oplock support.\n", strerror(errno) ));
1070       close(pfd[0]);
1071       close(pfd[1]);
1072       close(fd);
1073       return;
1074     }
1075
1076     oplock_pipe_read = pfd[0];
1077     oplock_pipe_write = pfd[1];
1078     close(fd);
1079
1080     lp_set_kernel_oplocks(True);
1081
1082     DEBUG(3,("check_kernel_oplocks: Kernel oplocks available and set to %s.\n",
1083           lp_kernel_oplocks() ? "True" : "False" ));
1084
1085   }
1086 #endif /* HAVE_KERNEL_OPLOCKS */
1087 }